From 66269a1d7e8016b6d67631ce5b0bf2cf5e587cbb Mon Sep 17 00:00:00 2001 From: jinyuttt Date: Wed, 11 Oct 2017 03:12:53 +0800 Subject: [PATCH 1/2] Signed-off-by: jinyuttt --- judt/bin/judp/DataStruct.class | Bin 0 -> 1431 bytes judt/bin/judp/PackagetCombin.class | Bin 0 -> 1936 bytes judt/bin/judp/PackagetSub.class | Bin 0 -> 2092 bytes judt/bin/judp/SocketControls$1.class | Bin 0 -> 2479 bytes judt/bin/judp/SocketControls.class | Bin 0 -> 2613 bytes judt/bin/judp/SocketReference.class | Bin 0 -> 1219 bytes judt/bin/judp/judpGroupSocket.class | Bin 0 -> 2340 bytes judt/bin/judp/judpSocket$1.class | Bin 0 -> 1136 bytes judt/bin/judp/judpSocketManager$1.class | Bin 0 -> 2369 bytes judt/bin/judp/judpSocketManager.class | Bin 0 -> 2999 bytes judt/bin/net/File/FileMonitor.class | Bin 0 -> 521 bytes judt/bin/net/File/FilesWatch$1.class | Bin 0 -> 2624 bytes judt/bin/net/File/FilesWatch.class | Bin 0 -> 2320 bytes judt/bin/net/File/PackagetCharSet.class | Bin 0 -> 411 bytes judt/bin/net/File/ReadXml.class | Bin 0 -> 3950 bytes judt/bin/net/File/RecviceFiles$1$1$1.class | Bin 0 -> 1491 bytes judt/bin/net/File/RecviceFiles$1$1.class | Bin 0 -> 5964 bytes judt/bin/net/File/RecviceFiles$1.class | Bin 0 -> 1663 bytes judt/bin/net/File/RecviceFiles.class | Bin 0 -> 2183 bytes judt/bin/net/File/SendFiles.class | Bin 0 -> 4072 bytes judt/bin/net/File/TestRecFiles.class | Bin 0 -> 1930 bytes judt/bin/net/File/TestSendFiles.class | Bin 0 -> 2040 bytes judt/bin/udt/UDTClient$1.class | Bin 0 -> 1333 bytes 23 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 judt/bin/judp/DataStruct.class create mode 100644 judt/bin/judp/PackagetCombin.class create mode 100644 judt/bin/judp/PackagetSub.class create mode 100644 judt/bin/judp/SocketControls$1.class create mode 100644 judt/bin/judp/SocketControls.class create mode 100644 judt/bin/judp/SocketReference.class create mode 100644 judt/bin/judp/judpGroupSocket.class create mode 100644 judt/bin/judp/judpSocket$1.class create mode 100644 judt/bin/judp/judpSocketManager$1.class create mode 100644 judt/bin/judp/judpSocketManager.class create mode 100644 judt/bin/net/File/FileMonitor.class create mode 100644 judt/bin/net/File/FilesWatch$1.class create mode 100644 judt/bin/net/File/FilesWatch.class create mode 100644 judt/bin/net/File/PackagetCharSet.class create mode 100644 judt/bin/net/File/ReadXml.class create mode 100644 judt/bin/net/File/RecviceFiles$1$1$1.class create mode 100644 judt/bin/net/File/RecviceFiles$1$1.class create mode 100644 judt/bin/net/File/RecviceFiles$1.class create mode 100644 judt/bin/net/File/RecviceFiles.class create mode 100644 judt/bin/net/File/SendFiles.class create mode 100644 judt/bin/net/File/TestRecFiles.class create mode 100644 judt/bin/net/File/TestSendFiles.class create mode 100644 judt/bin/udt/UDTClient$1.class diff --git a/judt/bin/judp/DataStruct.class b/judt/bin/judp/DataStruct.class new file mode 100644 index 0000000000000000000000000000000000000000..7de035ae17f5ba042c0fa203ba4d3804df6429dc GIT binary patch literal 1431 zcmZuw-%}f96g}VmNJ6@V7D{OhRInDa3np5trBJ8_iVY34HWgG}TsB*}G;A_qQ}x|H z#6J1LgU(RuIF;AVbVmON{|p~mJ$E-lJ5C?+-TU3|?z!ild-MF|??(VG;Z7Qw!oW_q z(Jn8!kz0>CT`x+*P&m2cK6J}XH{34Y+S>8GNFm)|O3e=yR8=9h)xCGm?PR>RLi$B=~qoF-n;Uhjj# z84D&-;+?gSMn=51ESyMUqZX{hJ7=LExioU@q!xrei*NazyY5!gR~W3dJh!>-b^^Kg zf<|;d*i$%F`(NX8EFKDV)4T6`4`M3cWKo2ZhOICZOA-dHa^;7}uf*+Jn8Gxh_^#u& z74pT+id}m{+MJ-2ER-c#Z+9t%?sX~N@EfzKWT4Prk6iD;s@v|-Hod0r@|(2VXvnn4 zQ|iSGXDnR7EZ?^MsMZR%W9}{aoeN54E;`9iCOl6*N112y+787J(lS7H~ zx(tV_P~s#faT_1v4*%!EemvpTV{bG61HLNm?*&|B9~wSlRu0Asl+q}wZ2v#hUh(VG zz24@TqnL9dkyXTeC1NgypW#TZ@Uz*tq?M%iN-BJePkK;)GTS6neTovSP9Ng(S3Kr6 zu08Ch=N%hz-Kbz== literal 0 HcmV?d00001 diff --git a/judt/bin/judp/PackagetCombin.class b/judt/bin/judp/PackagetCombin.class new file mode 100644 index 0000000000000000000000000000000000000000..9564b464509971783900903b99841a96c6fd5dcf GIT binary patch literal 1936 zcmb7EYf~F#6n@^2WRtKE%0;^ct@N4zZR!PDlUQrO+R#v_sUYBOvsqvv*^SFC4&ylE z-|#>9!FmadI847e<8N}*=iOvt5N2Alnceqt&U4QDoaelM{PpWGfVbc%2nh^r`_)Ef zNjG-%P1Boo>J`gY5EdBN*7x*GO}95Qij{jj&1m^Yua9B zwljP{vjx486Ns0sO1EIL4KH_>$dNC7(Cy|%2omYfHR3G`r4!3BYd=LGFKZ~__z zWvEwF#F1d?-j=n?$Sq1wR-H#x^lDY|OnOu6h4fkimvL3W6)6*`2HSEng?-N~_!}Fh ztKu526Z0!qZwP48qs8t?vz$aptC+wfBT!_rr~#Mra_5GMo5+wD?i6jRj3gHmcpYyl zctfB+2;32aO5siuW>2sA=HdnuOU<{Vc5E0hiQ6jf;BBH2mW66-woA^rZnu`ga|%d8 z@;`D*Ad7co^(cUFs+eAu@b^@_hXUanKH=}20pF$KHu@O>CH9<(*Dx+e_f>p=2Q89X zWeBIz>xBg7QBv^mL{FCYcRjPNVgZlXX1eR@`-aolr##NcrFc4-VsH=*ODZ1YLl)eT zC8adZaF;^J;)#lnq=F+x&D32cUO1wHn*H`v`{dNrcqRZP_U)oa+u#N@F(t3iLy^yBx9Oi dS+risKoiz8Z2iD#ceSUx>eSn*Q$4V<{{aY8vQPj3 literal 0 HcmV?d00001 diff --git a/judt/bin/judp/PackagetSub.class b/judt/bin/judp/PackagetSub.class new file mode 100644 index 0000000000000000000000000000000000000000..c39cbfb84bf22233dcd940992ae4ef4d2281c262 GIT binary patch literal 2092 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 M;8VU=!+i4ZUrH%&6aWAK literal 0 HcmV?d00001 diff --git a/judt/bin/judp/SocketReference.class b/judt/bin/judp/SocketReference.class new file mode 100644 index 0000000000000000000000000000000000000000..b701b6117c83f970b60969109511d11ef9e97641 GIT binary patch literal 1219 zcmah{U2hUW6g{&nP>@!-ZmE@iP_+u%L>}yev4q5!_|OoImel73rnnTLZg-8o`*(aW z(KPYFAK;Ht&&)0hD6#vnGjr$MbI(0B~`9 zW?>4H2kv{fK6FR@x-U=bucdpI00fpUbc)v#5Jv);hBxwprodXYHO+g`8OUyMSUVBO z9ee$e8-%_jxY};(p!sy%lX;}DTtF5}>EH2}gTQJ5X=DVhx4e;j9=`2JzwLI0Ot)I& zt~)$&eNUa^pc%aJE(A)gMg1I7FMCkU1uFj^g(`85^yB%2xV(_D!48_FO>t%Nf~JpD z*ICu6-WkfNgGIO*HOlA2-#vdk4*jlt=BbCV{~DtQ%4dN`jrQXi)_5qIGa=RY+QhHOD{y=V%C~LN~Q<b6m?pFB>~ENtsKiz*)Kg|RMS8PIEn8ZTqjlPeCw8L8j`ffk zcW{@usZR literal 0 HcmV?d00001 diff --git a/judt/bin/judp/judpGroupSocket.class b/judt/bin/judp/judpGroupSocket.class new file mode 100644 index 0000000000000000000000000000000000000000..43bccffd48186c50fddcf3126a29dbd9327dda7f GIT binary patch literal 2340 zcmZ`)X>$}+6g{sqNe{z=KoSBb5eOnAVHrh?NFquSmWe|WnGi_Cr8Con4xQ<7x+elE zZYb`!TYM6$sESoo34%73l$L(+gC8w_gOtC(Dyv-1>z>Sln5j(nyYJm|?mhRuJ3s&Z z?e_q-;sYI;K+|*~lZ&gbJ$a{)OF8Ldrl%t!uw>epHR86Bor(`nPMc{@AYxlCAIp-# zR>8CE_|AOZIFY2eM_@t9n#vkpA#Vz-yVaTAWFh0l4-AZkG(9`$RA)O=Q)XVErNTqm zED|S!J)Vm8rfn;0c{>DZIy%P~O23maW2nbc9ZLl2%fa^BhU-c+piw}dGQA;VhVe9Y zbcXmrLMbm#_?{S+VY!ZGffeP9s<|ar;5Md4pfDJL%^m+mDuM@+R0H%ZfIzFn0>l_* z(#o1cg_%h+KWa?cjH@B(qz!w_$XjY%G}iS7xyDd~)ex>xTjihCp*@Lp0-Rz;DhEKZR`$9)2es(fSU#{Cl8!9*6*HIdB~Jl4`Q zW|(rBslv`0KY#~yuyGoSSQWbx4`C+*w%omjJ79Q5&|VXYr(a?KQlK_%J1#q|8@na; zV6Q-o%qi1#EhnoqEaw;6$T*0kj)xiJeDvXt#6AoOEL8r1c!`04Z&0C+NIZi5;qI<% zCg)gLO4C?^AE9wX8HqoNF&zgeeTZM$k~oM%6fJMgIJ0Ic#>S4pTLjsS35iE>IHcTf zrcG;B-NQ2F=)94XkK;)lPn0N2TM~v+DdKugPNk8S$bfyVE=2KQH|DPYe(u6=pPaw(;pbsfZjZsn zQ|jiBy{dtW7hg5H4NszgS+=r~%aLB7O$qfsT#VVqafuUZu0%a2L{byv8Hr~VQN+p~ zabh@y7j!&7e_bsno*3SBJZ3Lib4MKNO25TGw^0C3V`<+x#Bco2b)G-al9+>j^dA{oI*Zr z?zYqf3Vs19hW}JF6p|4RbAK7K7I{%e2ukb@5MnRjfh|=2mZ1E zMS0T)>#&|rfev(*@Knq|tm`YR-Qc6^U>PYE?5t!4s{)kf@MIB%KG=*naRlzd-65X1 zK;By7{i^lWJTQkVt=f64RM>4kw)}u@AKQHNp2Np&y&Ct=wzZx|-5kzT9qFrD?edYR zwhXuXNFA&?H16ZED#N6YBR3nYD`>e6d%Pig4LM@CKA!e*at_gy z{zX^>3I=*aR~`rCB~0P;wKE@7mNhTZw)mqDzDN0D$Y>x z2)@H>eA9?{7_Z|E*8UQ$Z{jV!z0H`Kp#KG3h*kO@IHluMMEeu1^kip;72_0A6$GMT Y>Su4R{~=~HUeQI-QWw2PFAeYi3uO5qC;$Ke literal 0 HcmV?d00001 diff --git a/judt/bin/judp/judpSocket$1.class b/judt/bin/judp/judpSocket$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b55a36308466cc0e874029fdfd6c28b1991d0823 GIT binary patch literal 1136 zcmaJ>TTc^F5dKatE-j0ciz0Fri?ju)C?Z%uu@qBn!O+438p*Ofp$qNVW-mtH{S!X> zz%xdx@xjDb6QBG$Mx3*4K#{n~+1>eOzL{@lCj0Hz=Pv-J@lb(}p<~Z2)spg7F!g=z zM5h!47$SSx3oTjE#BOqJXOHWSf^!U=C+NB>gtk-R4CkD(VMlLJs@$nuDRRym!f+ND zx?}%%&%(DR@u}nL)uL+ zAVn~Aoh}lcA`yPe6=C$CSHUI9cuJ*;%jjch(R7{L-iM5wp*820oaDxGvC*Ye7y}qm zFi67xa;O-_6^76*cM4pTxJ7M=#gEAzMC7X&RS^Ay>^W3i!x({v-QZ@bHRqMrh%G5U zt|B2D6R;h#7QzH36M5%my`<9hRCZFrZUqiZexZaXjeF|QT^DX_+}WhxT|1}Ven)rvcln(<<=Zt%DmKh z%`r@&A|*w)*DOOg1xM5OissvLB<9Y?U|??Ls#_87?5w%<`S8_zBDS z=M(Rte!|5%`s)~ZgEnc`5j(*6JB)W@s*YQ)8S5B}^hHYLw?{vY{jK?lI_?}CeLbY4 z{g}f%iSt7WnL!)f*GSGf2`Qo%8x*mHQ9MNq&u|mZDSn$68Wx~q2~V($vL|}DA*?Cd yhcrbkP=y5qu!wt<^FHNP5%@{}joxhqvkEbm2=n0qMT6pcDBB9X$)?E`(DfT`68mic literal 0 HcmV?d00001 diff --git a/judt/bin/judp/judpSocketManager$1.class b/judt/bin/judp/judpSocketManager$1.class new file mode 100644 index 0000000000000000000000000000000000000000..bce98bfdd8bd9212ade80d0f6806caa577640e63 GIT binary patch literal 2369 zcmaJ@+fx%)9R3aoF2q$35ye}jP|HOLD6Le`Rs7M5kUx5Ix0~u5NcKq zRWZw!=d<&Z(oF=X*TfvtNR1n=rJnPPVMR$`_c~`ab&^uZ&Ds&{M7@Sx0(EOs*RdOW z1S$;El$lIZr@-O$1Bm(A$$C~Qdd|qq#Eo=M1pDxqhW!HD9x>`TfCi?A1{Y|+t*wqhhl1ll%; zB%Ac27yE|??BuXx*&gFKjHrfoR$!G$M+caeEkP7x%#!8U0^6I1T4I4~BELwGqj*X~ zm%!GQ79CIHm_Q{t2hlKH&Bg70dvfg9toWN$n zjY?Bm3({4DmH`WkgzQ7VhSSSYB?=}T0}3>p@tm~6Jgegz2J;l9om7aW6#XUQJ+JU$ zB@}&wD!_Ri7cg8bz)^v{q*UyRlrueTaol3ON|%w23hXR4#F*#O+LyIbJiG!4a(;0C z_McyWoAI;o*U#TXFoJP4Etdp#l=f1vwWnoVc}(cIj2GETw(*0Q!K?<0 z1uJqIxMs?<$G*}rry`rH*ibC zO@aMIq(R%0uA5DJGFg(MH&o|VrP(gtm}i)C3D+++}zVz?`qX==vu3&}?Kg1n2V;CyFKJr(8DMC1gDrTaVTG@c( zd)FsoB#j- literal 0 HcmV?d00001 diff --git a/judt/bin/judp/judpSocketManager.class b/judt/bin/judp/judpSocketManager.class new file mode 100644 index 0000000000000000000000000000000000000000..8a64772ef0e3d582d7519720ad556980b74721a6 GIT binary patch literal 2999 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 b-{S{9gY3~8_=*3TC=1i)pKH~7ng978G61T# literal 0 HcmV?d00001 diff --git a/judt/bin/net/File/FilesWatch.class b/judt/bin/net/File/FilesWatch.class new file mode 100644 index 0000000000000000000000000000000000000000..12a76a5bfcbfd5c31fb8649f2f8af290aa7f376a GIT binary patch literal 2320 zcma)7+fv(B6kW#{WE3S(6C5BAnuZYDP|U5jn9>FaEyO?*Q>V~dggAh}$W)S(_Ivu! zmp&vj!E~CLPM`ZxZP$?ukqKmg8J*i+>+HSuKHLBN`{!Q(Cb6p_CeYzXKR0ieW$^JH zo4&Q9AuiCqYd$q|Wz*Ttt!(T{%NNj|sZ;3+^cI3s$FAhI6gGerrTf&jWL}_Y)22}} zGzut+zH2+%Ji0^zYj1VOmF8xnNw`Oo=AWvvDh0A3zUtfMoKz?lmJrwR?>FI61duekYX61Lc0(XSi`h;=TeY@SRrvUH{- z5TC7VN*zt;H1H0Rtq{0opcyS{)@`5_x`yil=|H6m1fZh_oeF%zz$F-J_O5|8wCi{e z0~&6Two!4Fvf?kEFZVqIw=pQ7Z%cnpZkg3GQ`MW!oJ!GaKwd{0Sq&M1uJcF@3}INH z&5_Tdxut_|5J%5RJ%UjUITltx%>r3ix&N~z4}81g7#Ks6tOqOxzv!DR1lP2fu{I`E zE?4(Aq`PWvl(~~ER4lVxGF@A(>zi?Z$Mys|8?zP`EmJ0l>kPwgyq9N}gX@;egF02h zlYZbiA?XkkE!0d&=U&wE5aV36J?ODfFBv_bU!{Os{83 z39PY|aIK!2V*A#>ceu+vS}vRWd{~S4!N7tlm4sBiE{{$mj39T*%^D8`OL*ZOiHoF$T9bElNmKeve>=CYJ#UWDa z)0KUNp0y+N9-=SXbcp`!AGle=9UlLNL}93g_g|3U20O_RpL`R>Nij%j;5y<+an^+^ z=;nV9t(09qhUxSuZefB}sqj+%4t>DYFfkwEBQk!>RXbw;kydD2^D`3X_zCXvs~nyt zQaRj`9Xdq*1!u9~c0Je~q!@Q1H?-7mpnV_@8S&{!@RP)dfGf@zPjh9-H570u85Kk5 zt)LH|)xFu`sJuyLU!t#u&;Q2kb0yDx@jSrj?C0}!eUgk4$Z=+n7id8JXCpmiLQ7Jt7=SsQ^UHN)bRc5 z*iwuNvc?P8a_fxm@L?DtPym?FC>07#wA#`^;pxc4XQ75>-k$?XK0ATax literal 0 HcmV?d00001 diff --git a/judt/bin/net/File/PackagetCharSet.class b/judt/bin/net/File/PackagetCharSet.class new file mode 100644 index 0000000000000000000000000000000000000000..e32315cdc76bc84d7b7fd7bf95979c4e37df6044 GIT binary patch literal 411 zcmZ`#O-sW-5Pg$0A5EjJv3}sqi>RQvcn~aJ3OyASQhVRTCEXemh+F@cco01J1N>3q zYzznm7lxU6Gw<UUY7ZU4U@2ZiT!=D{ zZ_}mBG{I}KYvP0lX6AZ&zi;1c>% zRmz*yQ!4A3NDFB+t4tJgQ7hB8pgU?51K5Z{4B)e>UZ`in!Sp}-Y$ZslRh>z59AUV2 z-nsFPLpEdcZxFi15my#`cpL@+jyRj=M!_4xSFS8jPWF<3~C8PUnsdq}q*6KHH{joolz*tX2fcvk?oV2y$x&$?mjN$L5#hDNLvSR?maS)2Zv z*-URXt(zHv&1I~-5ieM#Jr%B8L*!c#QqUx@(Lr8urH0$EUZ9=_$@qt}1uM=-o0lDN z!%FZCc#DFK0!>T7Z>-U9J2nZ_5mx3*dQT3@pfXcOkHiSH1$QdALqKzYO7j{Tuu8>S z1!@X*vU67et!P)!#(XSZ)@#J+v8AB{on$lNybA1US)S+v%qmL4}$+)e3ho6xNQc4C);dzWar_eredw2}kFIdUF}dQ9h8R{+t0Z;*SU#I7*oG@^Z^23lG`LwVlgoIMtU`B1 za5)2vltNp($gq%WR*p~ZUBE2)$@zLG^#gjYRDFu&7P-LIYAIcWzEE?07}f9)PEs?* zq?xx_yzBr>{v!eiK;V>y(>PB5CARD&GQndS;xc+4lbcpR-x?h;(lr-Zb{m5#NT6Q< zDZVvpjfW@Gsc>GO3`aA$g6$Sp0OOdD$v#7&m3$_MyS=NGsZJxSfc4TM514c?a=Mi_ ztbDjP8!x1djNM%@Q#|c}9=EgBl!hGMPOW5&bJ0xR)-$q%J4)4dGXSi_G}v@(6xhiK zQ*n;Koi~F|cv_4(~s)$e;6a$%S$+AVJZ?3sx2H z7w|-f>hM8)Siy&=1qoDnkcOx5G;OSxzLX(p%Xd$W=;MQWn*6j?)$3xMLAJLT1=>}I zkK$tro~byeY}fE{e1gg}Z6hrUm_=U+Lx@k}(+WPt?o?^h@EIxW2D&+7O!6AY*mPCJ zbA%kqS{!|j71C>33O-L+JF0hjqpSOp6lINkLBkjEC0=`H^;E%-4QokJx)(25se~XS z7tycctLzCKa{P4-)A$ApRL|wuGzB`VCaV&s5s%m3d-Keks{^}p(fTfB*ETt>E- z=5htmeA|+s7HgiyQa4_zcFy}!lwl=kS$?#8%p4cxC>D9X$;|rmw#8ISGHVt5oO>Oz zh}>OBCJoC-xD8LiFW7O)HrZ^;ee^o|1Gt8X0Dg_%D0p@0y*ibr*fsoCQe2vS)Y523e!fWEGY@P+^w~TxtMUO+S3YKeHMmEM^n%o7; zoTpt-CjqyyOXqp9O8@!Q=`=uW;&tNX$0^|Bh@X{wDtrs`m$waS+Ge1>#DRx54;(YF z9(5dR?gIYS^Q~5X6O}f*>MbP@YwbLbmwpTPri&B0jvWx_U~iN}TsE8S>wo*Q`dMp|yCZ4;WY znWH=SDYg~&^0^P&`Ax9HakY&OY3RZL2D!U|Upt2}MAT-^KZqj?ZXcr_#t278xuOx? zc^>Ccutj0p5DLP+bzFZ8$K4P;PtcPFuKf36Ur#&_fAHbUZS?)oBJ{yIBt|=Dkc{}| zFg_ac&A^P*%pw)>i-;2P7hy$|X#^r_NG;;5;I9&@DPk(3PNOkW8>%hh-O}!i-WyVb z@4JEzcp%@sSMU)JuHadLNPw2lR<+d8@_bc`HiwI&p};I&n8BBWUn$~ip*lX?k;YLG zmm>9{`pb-SH?z~ji*tbSkMe4gzj2%|agjubdANrH*ooEHg*D7`Gxm^$`5XKDt=LvA3G-o!=)7ZqG%;zIM( UnYWy$i!v)=*}PuoK_0yEU%qMa4FCWD literal 0 HcmV?d00001 diff --git a/judt/bin/net/File/RecviceFiles$1$1$1.class b/judt/bin/net/File/RecviceFiles$1$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..7a7c29e6f484877bd5251152c8bf8ae4902316dc GIT binary patch literal 1491 zcma)5TTc@~6#k|cmaYR7L@OYbo7xt&;1wx?Qb3C>C39Eh(6Rdw6v*NYw7vbheG!hG%&Q)xeLB!X{)ASXz(5w?!b96n%~!IhQ!7U z%kah-;)w&~lFJOCtX&cjFf?%}XjBnI3r7S|hG0SpwB!v-%=zV2;Vjl-Xv^EWW-e=v zA@4iPkPM8Wdw+KW!xUK1@hufGbSOB+(6Mh09G&Q5Xw-CFxKt~K+<}?otHts?!%XY8 zrTdN}EH9n?LsAm!qIB06zR0NP#t8*+hSdLSarB^<%2lyVlc7D4ta;qkw2Xp&hQR&F z2u|X(f>TtDJ?$?VWwAu<;Yc9Kzzey2K3AO1&d*I18BXk-%5SAin2;q`NhLRDInE)? z5Oz%=DimH~Ho2@~7#9=}NaA$}7zmQALx-rR- zl?jA(Q)rHgY1~vW^Vd8TAG@9?bKH`0fi;~F=#?uBjAp54R}1$l55cvmT9txU*+IEl zw0);GzznUs$N8KrHPv$3(oNenthIvh9@r(0yVA4b2z^TPNPy=oOE_6mb6w#oSY(Lp zGXw-UikAK`STrh!le!+DKLVAwhlm=XyX2^;!FS-P_h^1ym1&i{>WkDi&_;JoI+A-B z?Q}96L3GE;H}VoB-n~ssq~3yWSrAZ4}M4m+5BHy+Wb5h{Ho4HgF1$ zki-*0=2MK}8Ns5A9G;_y7g)y2YAQXoaCcH^r4h)XpS<)Tgjw9C#PekT7{bAygpz;) prqCO0!^(FYiI8@I-UFD!Je?uJ-yJLv)k!Z!I^~Mh4zgNZzW@goTLS<9 literal 0 HcmV?d00001 diff --git a/judt/bin/net/File/RecviceFiles$1$1.class b/judt/bin/net/File/RecviceFiles$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..eb65b521ba4cb14317da513917019bf033d46146 GIT binary patch literal 5964 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 literal 0 HcmV?d00001 diff --git a/judt/bin/net/File/RecviceFiles$1.class b/judt/bin/net/File/RecviceFiles$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8a0ea43dc5f03705cd3b48a70cd3c9ba4a2f3785 GIT binary patch literal 1663 zcma)6>rN9v6#k|yY$*$JN5nftX%Twyh8FQsK`=!VYntG{Wf|x~-6eY=zL9@5QSp-a z06v9JqJFb2Lh3@?WM()*DhFxk-Ef11rV^+Hxv-?i+m(vh8t!~X@kPS%N{f)VKS z>z0?!GuTRGwAAjLw`|K_5I8e+j83K|kSIGFvI|Us4jnxy#4)6!7sCSasZ347sKAx~ z3qFMr3@KM8y@!Bn3`YEL%PcUaw2{Wiz=06~{ChHN&;ke`_)|mF}K&ODSY9tszU&ZAUt; zVTO5CZg+iw!KusFBt=$rsIR=W^`-g3&){Qyb)o@239eK%ZM0AueFQCbgAM0?m)fr*w9<)wL z6;{mSP4@o-DbQ2(4ReRh(z^8W@r0S*sO&_w-N9uS1&Sv*jLaeHDphp?xA|0%_R)u9 zR&ii8EZSzn@z|TI(yu!kI-X!zpu_VGm&Gu0G!d;HUdg-?&{u3*y5)x9dD6p0HbtDH zgL6!E3FR)nT`{CM*ei$seSNASdDg+vi&H%5qf`qmfs5JckLb_tV=(&-BWwFO{Sjk_ z;`sZ}>p9K?NN`q|d14hYgzGrZ9i4mhg9{w${1S#aD~vjIV_YY)AJG39mp}0VY>Knr zP+ZGS@8iZ7+>YVx@1InQL&5ZN1?!_5^K>{DLX0%sv>>_(a1RRvxgS~)EXh`V&_bQ$ zsu*<;YU~|_Sm?Ji+$@IvNQx%;NR#n)lV+4nlZSW|fzsb@l0QIUEai~FV=Qt_u&tM{ OLTP}k6iM|Jo68?f@`?@s literal 0 HcmV?d00001 diff --git a/judt/bin/net/File/RecviceFiles.class b/judt/bin/net/File/RecviceFiles.class new file mode 100644 index 0000000000000000000000000000000000000000..fb9addb269e0b2bb40bcb70a417492a6374ae455 GIT binary patch literal 2183 zcmah~YgZdp6x|mRCXCaTQeIM^r2@@^k|J2qAg!fE(eMzE3gTm!+`>SZ!I=s6xA+_U z-~&RJtmO~zSNJP@tmSgK?__8K4K`UTcjnx?_c{CAb54Hy_m^J*jH9HXL7?4{L3YM2 z%IuP~4s1)RXJ121pk>EAFtbI|*~%_#?no;TX!50ZAU%Pr`JGZ>KdXM0LsL$m*^}1F zwkOSkKx@7VuGn~>vFL6IbXT@YfnChfuw|1!&sBQrNWmt1EqXcdc!FE;eb+7e0z)-; z%XO@h=Se5XK7J;xQs8p+|`g3=&OpUlT_wr6mJS#bL6+vrnM~#l}laZm5}>1Pob1L@Y6d{ zj>ipL!ew4Yux;};JM(o5kk`jr3m&OzXs?$$UT547Opis`QD=WPwXR`OzzAj8Zdl?v za+p%NnNUv;47`tr^dq0ye!x&zB9#{!lV|1$d}c|nR&^f8A|)iGwHvo;G$CC5>~(h$}+D`&?xBd(sE#0yL0A#RHF&gvZU`1+!aV)sH)CnImL|%-2We( z8dt9>LCTGSU^!=AK^D%w7X#=NI400@rs7|kV*0XM@+za0qq26ej;MNMSJDS;MGSq6 z>jop~M;qC$qc>zXDqMIA_d-8!VCtS=`jB(Mv>+p$1u7$F$a-VbCcua z56t3EEa5Nq*WaOn@k(qj6l`EKRKR#)p+J2G79sJJ{3HBsVVn81=`R8C54tquS`yg7 zZlrcFRL|N_LVn<}+Dq*VT{5wR6tPzaGIkzvs|Mo0tpmxNhxFG#_VG;w8Q`iuv7gX) V9#Ji}26$o2J_4>fF$)R={0DW3)~Nsh literal 0 HcmV?d00001 diff --git a/judt/bin/net/File/SendFiles.class b/judt/bin/net/File/SendFiles.class new file mode 100644 index 0000000000000000000000000000000000000000..27ad4222f31ee8362a0d2c96bc6b37bf1c70880f GIT binary patch literal 4072 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 literal 0 HcmV?d00001 diff --git a/judt/bin/udt/UDTClient$1.class b/judt/bin/udt/UDTClient$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1e91d8c5ddf13d1f86c2e8fe38588b7663429331 GIT binary patch literal 1333 zcmaJ>TW=Fb6#gc5vWZ!Ua|6mP0Ss}%#RO7Ho0OYlh=ZK~HUS|dv{{dm1!vaUOE2&J z6MgPO-YQYGZiNs6A+-qc07$J6LcH)d5aFA3NH9gLG@hC7ob#RUoIUGDZ*SiPFp3KX zS_C@7N|3oUQO;H!se;sqfw(~OhV`A5sak42Gc$KX+JS*Kf$lZ*VyKigSCs;7!Ghzb z4w0zP#56|JxTBolI0Mrk*@k8X;#s#MJ0P&$gn{-1V(2u{fuukztsOcGj*`>i;+*u# zja=OY*S4y&mgngE3K-V{1iG42q(&$p=7lPOP58pVX69+qXJQMs3bb3cE&Zr~)c;gQ zl#Rxe=;XL+EP?IlH?V^VHC>a@!~k{*bj-`3O|NE2Ub@6MX%sGt;B_RX?q*?d=D;cElO1hz*(Vc=9V zwyW&W^Ef)0va={J@r9fC25i1r%ohszQZ73)Jy8aLuq8@v=-Kj&qep+k>SuFM3u4D|%C5S;qvne;Sa2&QW^^N4HAsImuaxw% zRm=CK&sm{Pu2zU-Qhxy~zJ;p;38L$GI>x(362trcfI0jpHr$GQx-=G9bo3o`^KLRm zqdn;5&YF>Iu!sR>i4nUJ8z251=3m%Y$F@3l)sg-geHyCc;1b4)`|B84T7LB#j`m`_ zj^jTG(KVRdnyf7Rvixw>uczUMb$UO&wEXKWviD&d`Z-hIVghHm52C=*v$SZfQ<1`Z zRQ!ORf7ACLdOu_b9wCLt^nSwme2OD@MuvaM@gFAfoE$I6@)GCq3T52KWxS4 Date: Wed, 11 Oct 2017 03:18:04 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .metadata/.bak_0.log | 12431 ++++++++++++++++ .metadata/.log | 10661 ++++++++----- .metadata/.mylyn/.tasks.xml.zip | Bin 235 -> 235 bytes .../0/209a8eaa21ac001710ff8a7c6bda0fb8 | 290 + .../0/c0b151e22dac001710ff8a7c6bda0fb8 | 99 + .../0/e03d304ed7ac001716b9ca6d5abb90bc | 279 + .../1/80f6654c19ac001710ff8a7c6bda0fb8 | 12 + .../1/d00788f456ac00171c63d91e40f02a62 | 151 + .../1/e085ced59aad0017181ed9113883eda9 | 502 + .../1/f0f3e82c6fa800171a8482560d609ceb | 104 + .../10/00c09b1e59ac00171c63d91e40f02a62 | 149 + .../10/709e69df58ac00171c63d91e40f02a62 | 152 + .../10/d0aa129d98ad0017181ed9113883eda9 | 36 + .../10/f0565a8d18ac001710ff8a7c6bda0fb8 | 12 + .../12/90ddb49ea2ad0017181ed9113883eda9 | 103 + .../12/e051f64398ad0017181ed9113883eda9 | 43 + .../13/10bc98feb5ac001716b9ca6d5abb90bc | 192 + .../13/e0517759cbac001716b9ca6d5abb90bc | 194 + .../14/0005620c24ac001710ff8a7c6bda0fb8 | 328 + .../14/b0bb513ec8ac001716b9ca6d5abb90bc | 195 + .../14/c081423d1cac001710ff8a7c6bda0fb8 | 32 + .../15/503d09ac4fac001710ff8a7c6bda0fb8 | 246 + .../16/0013e7ed04ac001710ff8a7c6bda0fb8 | 32 + .../16/109c5e88d6ac001716b9ca6d5abb90bc | 288 + .../16/406135d6daac001716b9ca6d5abb90bc | 284 + .../16/c058bb4b62a800171a8482560d609ceb | 12 + .../16/d0bf190435ac001710ff8a7c6bda0fb8 | 337 + .../17/10936cbe05ac001710ff8a7c6bda0fb8 | 92 + .../17/30f8db4bd8ac001716b9ca6d5abb90bc | 338 + .../17/807fbc93e2ac001716b9ca6d5abb90bc | 199 + .../17/80cd43731aac001710ff8a7c6bda0fb8 | 73 + .../17/a0ce86b02dac001710ff8a7c6bda0fb8 | 100 + .../17/c0591a57b5ad0017181ed9113883eda9 | 522 + .../18/006c2690d8ac001716b9ca6d5abb90bc | 368 + .../18/307f6ce864a800171a8482560d609ceb | 58 + .../18/6065932703ac001710ff8a7c6bda0fb8 | 16 + .../18/c05c601f6da800171a8482560d609ceb | 42 + .../18/f0e7afc269a800171a8482560d609ceb | 114 + .../19/00d683551aac001710ff8a7c6bda0fb8 | 77 + .../19/40df30479fad0017181ed9113883eda9 | 12 + .../19/6063b7c5ceac001716b9ca6d5abb90bc | 216 + .../19/60d4a2c04fac001710ff8a7c6bda0fb8 | 139 + .../19/c03f59b4f3ab001710ff8a7c6bda0fb8 | 71 + .../19/d056ace51fac001710ff8a7c6bda0fb8 | 43 + .../1a/f0fb59a4a1ad0017181ed9113883eda9 | 50 + .../1b/201f78bc6da800171a8482560d609ceb | 56 + .../1c/404d73a415ac001710ff8a7c6bda0fb8 | 35 + .../1c/509f6ba4c9ac001716b9ca6d5abb90bc | 193 + .../1d/d09bb2d219ac001710ff8a7c6bda0fb8 | 74 + .../1d/e04931bbe4ac001716b9ca6d5abb90bc | 224 + .../1e/6080d540c8ac001716b9ca6d5abb90bc | 195 + .../1e/c080de4460ac00171ca19969f19d2325 | 238 + .../1e/e06c053c27ac001710ff8a7c6bda0fb8 | 328 + .../1f/20acb57d69a800171a8482560d609ceb | 95 + .../1f/70a02b246da800171a8482560d609ceb | 56 + .../1f/b0635746e5ac001716b9ca6d5abb90bc | 247 + .../1f/c0c69f405ca800171a8482560d609ceb | 211 + .../1f/e004bd9ee7ac001716b9ca6d5abb90bc | 36 + .../2/b0e3a7446ba800171a8482560d609ceb | 112 + .../20/4057838a1aac001710ff8a7c6bda0fb8 | 0 .../20/602e70256da800171a8482560d609ceb | 56 + .../20/c06bb2f50eac001710ff8a7c6bda0fb8 | 101 + .../21/10bf9d62dbac001716b9ca6d5abb90bc | 368 + .../21/b0314608c5ad0017181ed9113883eda9 | 516 + .../21/f0f57f2ec5ad0017181ed9113883eda9 | 520 + .../22/3024d0d16da800171a8482560d609ceb | 42 + .../22/40a8ff391bac001710ff8a7c6bda0fb8 | 15 + .../22/70ca7fc634ac001710ff8a7c6bda0fb8 | 333 + .../22/8070220c0fac001710ff8a7c6bda0fb8 | 112 + .../23/00e997b8a2ad0017181ed9113883eda9 | 55 + .../23/301509806da800171a8482560d609ceb | 35 + .../23/a089455d57ac00171c63d91e40f02a62 | 152 + .../23/d00f297c26ac001710ff8a7c6bda0fb8 | 87 + .../24/40719255f4ab001710ff8a7c6bda0fb8 | 27 + .../24/5048587004ac001710ff8a7c6bda0fb8 | 79 + .../24/70abceb2e0ac001716b9ca6d5abb90bc | 151 + .../24/d09c215ae5ac001716b9ca6d5abb90bc | 247 + .../25/c0e0b2fbe2ac001716b9ca6d5abb90bc | 199 + .../26/204e38905bac00171c63d91e40f02a62 | 246 + .../26/90b7a18162a800171a8482560d609ceb | 15 + .../26/c0f91e9d5ca800171a8482560d609ceb | 232 + .../27/001fcd525dac00171c63d91e40f02a62 | 490 + .../27/6089d24d1aac001710ff8a7c6bda0fb8 | 77 + .../27/a02fb0af2bac001710ff8a7c6bda0fb8 | 88 + .../27/b07f5b0fb5ad0017181ed9113883eda9 | 516 + .../27/f03094536aa800171a8482560d609ceb | 16 + .../28/20611a6ec3ad0017181ed9113883eda9 | 492 + .../28/b08c10a81fac001710ff8a7c6bda0fb8 | 38 + .../29/306a36aed6ac001716b9ca6d5abb90bc | 289 + .../2a/507d3e2903ac001710ff8a7c6bda0fb8 | 21 + .../2a/b06d26c4cfac001716b9ca6d5abb90bc | 233 + .../2a/d05059bbcfac001716b9ca6d5abb90bc | 233 + .../2b/00218dfa88ad0017181ed9113883eda9 | 191 + .../2b/6049060569a800171a8482560d609ceb | 76 + .../2b/b0ae6971bcac001716b9ca6d5abb90bc | 604 + .../2c/00da54ff0eac001710ff8a7c6bda0fb8 | 107 + .../2c/30197d17d7ac001716b9ca6d5abb90bc | 270 + .../2c/801fec2f59ac00171c63d91e40f02a62 | 152 + .../2c/b041f93e67a800171a8482560d609ceb | 64 + .../2c/d0baafa565a800171a8482560d609ceb | 25 + .../2d/10bf61d937ac001710ff8a7c6bda0fb8 | 100 + .../2d/6073c07321ac001710ff8a7c6bda0fb8 | 297 + .../2d/60a67df369a800171a8482560d609ceb | 113 + .../2d/60cfdf2409ac001710ff8a7c6bda0fb8 | 99 + .../2e/200d3c4164a800171a8482560d609ceb | 45 + .../2e/30535d40c5ad0017181ed9113883eda9 | 522 + .../2e/4043e9f84fac001710ff8a7c6bda0fb8 | 146 + .../2e/603775eeb3ad0017181ed9113883eda9 | 515 + .../2e/6047b62203ac001710ff8a7c6bda0fb8 | 22 + .../2e/b08f394dc5ad0017181ed9113883eda9 | 522 + .../2e/c0aa731ac5ad0017181ed9113883eda9 | 516 + .../2e/f0a141dda3ad0017181ed9113883eda9 | 43 + .../2f/1088bc2468a800171a8482560d609ceb | 77 + .../2f/2054ba4000ac001710ff8a7c6bda0fb8 | 14 + .../2f/20ad410dc5ad0017181ed9113883eda9 | 516 + .../2f/804aa08d21ac001710ff8a7c6bda0fb8 | 288 + .../3/60d321ea61ac00171ca19969f19d2325 | 248 + .../3/d0bbd534b5ac001716b9ca6d5abb90bc | 354 + .../30/4057ad45c5ad0017181ed9113883eda9 | 522 + .../30/a07a6f8a9aad0017181ed9113883eda9 | 502 + .../30/c0f68a50d7ac001716b9ca6d5abb90bc | 284 + .../30/f0d85be699ad0017181ed9113883eda9 | 368 + .../31/0079a8fd4fac001710ff8a7c6bda0fb8 | 150 + .../31/106f933126ac001710ff8a7c6bda0fb8 | 89 + .../32/50142e9c31ac001710ff8a7c6bda0fb8 | 338 + .../33/30bcc157d7ac001716b9ca6d5abb90bc | 284 + .../33/703f445cc9ac001716b9ca6d5abb90bc | 605 + .../33/b04561b206ac001710ff8a7c6bda0fb8 | 96 + .../34/b06540c026ac001710ff8a7c6bda0fb8 | 234 + .../35/204ce0dff7ab001710ff8a7c6bda0fb8 | 86 + .../35/8092462f1eac001710ff8a7c6bda0fb8 | 27 + .../36/106b6f256da800171a8482560d609ceb | 56 + .../36/406a1f2526ac001710ff8a7c6bda0fb8 | 54 + .../36/60ac64f0e4ac001716b9ca6d5abb90bc | 235 + .../36/d0590bba1bac001710ff8a7c6bda0fb8 | 55 + .../37/204743b36aa800171a8482560d609ceb | 35 + .../37/a01fdf541cac001710ff8a7c6bda0fb8 | 39 + .../38/101a00e86aa800171a8482560d609ceb | 0 .../38/c0d1e01c26ac001710ff8a7c6bda0fb8 | 56 + .../39/30cdd9d35aac00171c63d91e40f02a62 | 154 + .../39/803bf78dceac001716b9ca6d5abb90bc | 206 + .../39/f089629426ac001710ff8a7c6bda0fb8 | 92 + .../3a/50db850527ac001710ff8a7c6bda0fb8 | 243 + .../3a/600fb8d2a0ad0017181ed9113883eda9 | 79 + .../3a/c0bd03d4e6ac001716b9ca6d5abb90bc | 249 + .../3b/0009e5c7a3ad0017181ed9113883eda9 | 36 + .../3b/20158b335ca800171a8482560d609ceb | 202 + .../3c/20d0ca0806ac001710ff8a7c6bda0fb8 | 96 + .../3d/a0e3d71e22ac001710ff8a7c6bda0fb8 | 212 + .../3d/b0e4032f6fa800171a8482560d609ceb | 110 + .../3d/c0b81a6bdeac001716b9ca6d5abb90bc | 186 + .../3d/d0dec61a6aa800171a8482560d609ceb | 113 + .../3e/105906a604ac001710ff8a7c6bda0fb8 | 86 + .../3e/10c01b9bd8ac001716b9ca6d5abb90bc | 152 + .../3e/90c8f6fe1bac001710ff8a7c6bda0fb8 | 28 + .../3f/0095c3b32bac001710ff8a7c6bda0fb8 | 88 + .../3f/00c3b2bf97ad0017181ed9113883eda9 | 150 + .../3f/20ae3effb7ac001716b9ca6d5abb90bc | 193 + .../3f/90252382e1ac001716b9ca6d5abb90bc | 193 + .../3f/a091f71264a800171a8482560d609ceb | 27 + .../3f/d057016d64a800171a8482560d609ceb | 50 + .../4/30a058a9e7ac001716b9ca6d5abb90bc | 36 + .../4/40be8a05e0ac001716b9ca6d5abb90bc | 189 + .../4/60fff865d8ac001716b9ca6d5abb90bc | 358 + .../40/10dbf0de4fac001710ff8a7c6bda0fb8 | 141 + .../40/70a06d54ddac001716b9ca6d5abb90bc | 605 + .../40/a02a6e9dcfac001716b9ca6d5abb90bc | 232 + .../40/a05bab671aac001710ff8a7c6bda0fb8 | 77 + .../40/c0b85c6bf7ab001710ff8a7c6bda0fb8 | 130 + .../41/f064f58963ac00171f75fe2361138dfd | 239 + .../41/f07d59bd1cac001710ff8a7c6bda0fb8 | 44 + .../42/101d91fd26ac001710ff8a7c6bda0fb8 | 234 + .../42/3010ed2dd2ac001716b9ca6d5abb90bc | 233 + .../42/e050c8c64fac001710ff8a7c6bda0fb8 | 140 + .../42/f048fd99a2ad0017181ed9113883eda9 | 102 + .../43/60189468a3ad0017181ed9113883eda9 | 104 + .../43/80c63bcb21ac001710ff8a7c6bda0fb8 | 44 + .../44/00022a6de4ac001716b9ca6d5abb90bc | 219 + .../44/10c21fc9d6ac001716b9ca6d5abb90bc | 248 + .../44/c0e041dbe7ac001716b9ca6d5abb90bc | 42 + .../44/e0948e82cead00171536fea4e2c2e8be | 356 + .../44/e0b7669b5ba800171a8482560d609ceb | 196 + .../45/30c1c047b5ad0017181ed9113883eda9 | 519 + .../45/80fb200424ac001710ff8a7c6bda0fb8 | 324 + .../45/b017204bd7ac001716b9ca6d5abb90bc | 279 + .../46/60c6b52059ac00171c63d91e40f02a62 | 152 + .../46/e0878eb7f8ab001710ff8a7c6bda0fb8 | 347 + .../47/007297c0b8ac001716b9ca6d5abb90bc | 602 + .../47/d00bbfdca0ad0017181ed9113883eda9 | 43 + .../48/d0a3f354a2ad0017181ed9113883eda9 | 55 + .../48/d0b6053b5ba800171a8482560d609ceb | 174 + .../49/3039da0c69a800171a8482560d609ceb | 81 + .../49/607bc94804ac001710ff8a7c6bda0fb8 | 71 + .../4a/80cbba742aad001713e0de43c08806fd | 189 + .../4a/d05deaacb8ac001716b9ca6d5abb90bc | 601 + .../4a/d0c629a9cdac001716b9ca6d5abb90bc | 205 + .../4b/a035f5deb4ad0017181ed9113883eda9 | 515 + .../4b/a0ad7bad60a800171a8482560d609ceb | 268 + .../4c/00556ecf13ac001710ff8a7c6bda0fb8 | 27 + .../4c/f007c03509ac001710ff8a7c6bda0fb8 | 99 + .../4c/f03eaf6868a800171a8482560d609ceb | 70 + .../4c/f0982c98e4ac001716b9ca6d5abb90bc | 223 + .../4d/400ac46406ac001710ff8a7c6bda0fb8 | 70 + .../4d/b0a68230f7ab001710ff8a7c6bda0fb8 | 130 + .../4e/30bcb47629ad001713e0de43c08806fd | 187 + .../4e/503da3aa52ac001710ff8a7c6bda0fb8 | 147 + .../4e/903b8e7ad6ac001716b9ca6d5abb90bc | 279 + .../4e/b0d52a15e0ac001716b9ca6d5abb90bc | 188 + .../4f/200a00ac60a800171a8482560d609ceb | 262 + .../4f/305dcf6953ac001710ff8a7c6bda0fb8 | 337 + .../4f/b0a7c36b64a800171a8482560d609ceb | 45 + .../50/002264c122ac001710ff8a7c6bda0fb8 | 218 + .../50/10970a0ca1ad0017181ed9113883eda9 | 50 + .../50/300b00e08ead0017181ed9113883eda9 | 89 + .../50/6044e0b534ac001710ff8a7c6bda0fb8 | 338 + .../50/607944715ca800171a8482560d609ceb | 226 + .../50/80d9f8332aac001710ff8a7c6bda0fb8 | 99 + .../50/c03beacccfac001716b9ca6d5abb90bc | 233 + .../51/20a6e040d7ac001716b9ca6d5abb90bc | 274 + .../51/30d701b321ac001710ff8a7c6bda0fb8 | 295 + .../51/900a2db5a0ad0017181ed9113883eda9 | 61 + .../51/c06ec8a7a1ad0017181ed9113883eda9 | 51 + .../52/60fcfcdf2aad001713e0de43c08806fd | 190 + .../52/80a9f5a752ac001710ff8a7c6bda0fb8 | 150 + .../52/a0e88386d6ac001716b9ca6d5abb90bc | 283 + .../53/60e8bdb026ac001710ff8a7c6bda0fb8 | 234 + .../53/c0fa7ce21dac001710ff8a7c6bda0fb8 | 65 + .../53/e0cf12f56aa800171a8482560d609ceb | 12 + .../54/d0d788fe58ac00171c63d91e40f02a62 | 149 + .../54/f09c3717a1ad0017181ed9113883eda9 | 50 + .../55/2001542903ac001710ff8a7c6bda0fb8 | 21 + .../55/e05f7dc334ac001710ff8a7c6bda0fb8 | 339 + .../56/30539028d8ac001716b9ca6d5abb90bc | 146 + .../56/40e91a0269a800171a8482560d609ceb | 72 + .../56/509c645db5ad0017181ed9113883eda9 | 523 + .../57/60df03ff04ac001710ff8a7c6bda0fb8 | 33 + .../57/70fe88816da800171a8482560d609ceb | 35 + .../57/c01e4b7e21ac001710ff8a7c6bda0fb8 | 288 + .../57/c030fc7309ac001710ff8a7c6bda0fb8 | 101 + .../57/d0125e1f6da800171a8482560d609ceb | 42 + .../58/50cfdaa722ac001710ff8a7c6bda0fb8 | 212 + .../58/80a5207c6fa800171a8482560d609ceb | 269 + .../59/2091b446e0ac001716b9ca6d5abb90bc | 148 + .../5a/10ee44b7a0ad0017181ed9113883eda9 | 79 + .../5a/30d29f9969a800171a8482560d609ceb | 113 + .../5a/b091bc44e0ac001716b9ca6d5abb90bc | 149 + .../5a/c0e40d3ea0ad0017181ed9113883eda9 | 52 + .../5a/c0e9c48ee4ac001716b9ca6d5abb90bc | 220 + .../5b/b0bdcfc2d7ac001716b9ca6d5abb90bc | 143 + .../5c/20504804c5ad0017181ed9113883eda9 | 516 + .../5d/6043da1d1aac001710ff8a7c6bda0fb8 | 74 + .../5d/70679366d4ac001716b9ca6d5abb90bc | 250 + .../5e/205e2eb706ac001710ff8a7c6bda0fb8 | 97 + .../5e/30073a3d25ac001710ff8a7c6bda0fb8 | 233 + .../5e/60083557deac001716b9ca6d5abb90bc | 183 + .../5e/80cf2f975ca800171a8482560d609ceb | 232 + .../5f/10f8023268a800171a8482560d609ceb | 81 + .../5f/d03f8ec3e4ac001716b9ca6d5abb90bc | 234 + .../6/40f9d9b9ceac001716b9ca6d5abb90bc | 210 + .../60/0049134464a800171a8482560d609ceb | 45 + .../60/2023350a64a800171a8482560d609ceb | 27 + .../60/30e12f8c69a800171a8482560d609ceb | 99 + .../60/b0bfd1a019ac001710ff8a7c6bda0fb8 | 74 + .../61/109c41f905ac001710ff8a7c6bda0fb8 | 97 + .../61/60416b18e5ac001716b9ca6d5abb90bc | 239 + .../61/a02c15f303ac001710ff8a7c6bda0fb8 | 70 + .../62/d0dc45525ba800171a8482560d609ceb | 177 + .../63/1027745f23ac001710ff8a7c6bda0fb8 | 232 + .../63/2084e14ee5ac001716b9ca6d5abb90bc | 246 + .../63/40a19ee8ceac001716b9ca6d5abb90bc | 220 + .../63/f0ff4653cbac001716b9ca6d5abb90bc | 195 + .../64/00f0eed5f6ab001710ff8a7c6bda0fb8 | 114 + .../64/d0b50df3b4ad0017181ed9113883eda9 | 187 + .../65/20253f0eb3ad0017181ed9113883eda9 | 503 + .../65/50bfc894a6ad0017181ed9113883eda9 | 52 + .../65/c0b5f764b9ad0017181ed9113883eda9 | 356 + .../65/d0bc506103ac001710ff8a7c6bda0fb8 | 24 + .../65/e0d96e5a1eac001710ff8a7c6bda0fb8 | 28 + .../66/10f59fb9a0ad0017181ed9113883eda9 | 79 + .../66/704245e5e1ac001716b9ca6d5abb90bc | 148 + .../66/804c48ac2bac001710ff8a7c6bda0fb8 | 88 + .../66/f01f9db921ac001710ff8a7c6bda0fb8 | 300 + .../66/f0ac4e11e0ac001716b9ca6d5abb90bc | 188 + .../67/1081b1f8b5ac001716b9ca6d5abb90bc | 191 + .../67/60dc22d413ac001710ff8a7c6bda0fb8 | 28 + .../67/80be36cff8ab001710ff8a7c6bda0fb8 | 351 + .../67/c071fbe65ea800171a8482560d609ceb | 0 .../67/d0d5236bf4ab001710ff8a7c6bda0fb8 | 27 + .../69/b06da8a2d8ac001716b9ca6d5abb90bc | 152 + .../69/d0e5e1f3a0ad0017181ed9113883eda9 | 45 + .../6a/40965eabcfac001716b9ca6d5abb90bc | 232 + .../6a/80d7e50364a800171a8482560d609ceb | 27 + .../6b/00bc254e26ac001710ff8a7c6bda0fb8 | 89 + .../6c/301bb18ff7ab001710ff8a7c6bda0fb8 | 83 + .../6d/408eaf421dac001710ff8a7c6bda0fb8 | 61 + .../6d/a0cd93471cac001710ff8a7c6bda0fb8 | 33 + .../6d/f04b670427ac001710ff8a7c6bda0fb8 | 243 + .../6e/001449b561ac00171ca19969f19d2325 | 155 + .../6e/40913b1af8ab001710ff8a7c6bda0fb8 | 88 + .../6e/c0a030dfdfac001716b9ca6d5abb90bc | 187 + .../6e/d0f5ffe8f7ab001710ff8a7c6bda0fb8 | 87 + .../6f/a0409b8eb3ad0017181ed9113883eda9 | 514 + .../6f/c03e69c56da800171a8482560d609ceb | 42 + .../7/509a29f366a800171a8482560d609ceb | 54 + .../7/a0002b2d5ca800171a8482560d609ceb | 202 + .../7/d084703024ac001710ff8a7c6bda0fb8 | 233 + .../70/201ef600e4ac001716b9ca6d5abb90bc | 205 + .../70/907af0871eac001710ff8a7c6bda0fb8 | 28 + .../71/3084b6db9aad0017181ed9113883eda9 | 43 + .../71/5038a5acd5ac001716b9ca6d5abb90bc | 264 + .../71/604351d567a800171a8482560d609ceb | 70 + .../71/60903e2466a800171a8482560d609ceb | 45 + .../71/80add8d6d7ac001716b9ca6d5abb90bc | 143 + .../71/b04f3e4167a800171a8482560d609ceb | 66 + .../72/10921d306fa800171a8482560d609ceb | 115 + .../72/a0a4851566a800171a8482560d609ceb | 38 + .../72/f02fa8b892ad0017181ed9113883eda9 | 503 + .../73/00abaea82bac001710ff8a7c6bda0fb8 | 88 + .../73/a037d3e934ac001710ff8a7c6bda0fb8 | 333 + .../73/d0e9d0895fac00171ca19969f19d2325 | 154 + .../74/3091ac6c7fad0017181ed9113883eda9 | 191 + .../74/70995f1f6da800171a8482560d609ceb | 42 + .../74/a0ba2744b2ac001716b9ca6d5abb90bc | 191 + .../74/b065917426ac001710ff8a7c6bda0fb8 | 87 + .../75/0052421d5da800171a8482560d609ceb | 238 + .../75/00cbed535ca800171a8482560d609ceb | 216 + .../75/70afe12ddbac001716b9ca6d5abb90bc | 605 + .../75/a0430dbae1ac001716b9ca6d5abb90bc | 149 + .../75/b0a223eb03ac001710ff8a7c6bda0fb8 | 70 + .../76/5036ee8cd6ac001716b9ca6d5abb90bc | 288 + .../77/403c36a21aac001710ff8a7c6bda0fb8 | 12 + .../78/10e15310c3ad0017181ed9113883eda9 | 525 + .../78/8067edbee4ac001716b9ca6d5abb90bc | 229 + .../78/9086b899d8ac001716b9ca6d5abb90bc | 152 + .../78/b07ba83069a800171a8482560d609ceb | 91 + .../79/6084a52a24ac001710ff8a7c6bda0fb8 | 328 + .../79/e07207b3d9ac001716b9ca6d5abb90bc | 149 + .../7a/60f5446d26ac001710ff8a7c6bda0fb8 | 87 + .../7a/d078325404ac001710ff8a7c6bda0fb8 | 79 + .../7c/00baf1751bac001710ff8a7c6bda0fb8 | 14 + .../7c/708d70c31aac001710ff8a7c6bda0fb8 | 0 .../7c/f009da97d5ac001716b9ca6d5abb90bc | 255 + .../7d/50c2175e68a800171a8482560d609ceb | 78 + .../7d/50df241c27ac001710ff8a7c6bda0fb8 | 328 + .../7d/604ba6846aa800171a8482560d609ceb | 209 + .../7d/90850181b8ac001716b9ca6d5abb90bc | 600 + .../7d/a00a34b931ac001710ff8a7c6bda0fb8 | 338 + .../7d/b0fe5132d7ac001716b9ca6d5abb90bc | 291 + .../7d/d043da1809ac001710ff8a7c6bda0fb8 | 98 + .../7d/f014ead31aac001710ff8a7c6bda0fb8 | 12 + .../7e/006d75ddffab001710ff8a7c6bda0fb8 | 79 + .../7e/401863511cac001710ff8a7c6bda0fb8 | 38 + .../7e/b067998b05ac001710ff8a7c6bda0fb8 | 93 + .../7f/3056569822ac001710ff8a7c6bda0fb8 | 208 + .../7f/40c53669d8ac001716b9ca6d5abb90bc | 363 + .../7f/60f67dd3feab001710ff8a7c6bda0fb8 | 76 + .../7f/b07dd0961bac001710ff8a7c6bda0fb8 | 14 + .../80/105d7f665ca800171a8482560d609ceb | 223 + .../80/d030786d1aac001710ff8a7c6bda0fb8 | 76 + .../81/20dcb587daac001716b9ca6d5abb90bc | 239 + .../81/500e2b00d6ac001716b9ca6d5abb90bc | 273 + .../82/0096696f19ac001710ff8a7c6bda0fb8 | 14 + .../82/209d88b969a800171a8482560d609ceb | 114 + .../82/50bd4a31d6ac001716b9ca6d5abb90bc | 279 + .../82/7042778204ac001710ff8a7c6bda0fb8 | 86 + .../82/801757f229ac001710ff8a7c6bda0fb8 | 99 + .../82/8060528c6da800171a8482560d609ceb | 35 + .../83/30fc38d25fac00171ca19969f19d2325 | 236 + .../83/d01fa7f1d6ac001716b9ca6d5abb90bc | 253 + .../83/d02d0d08f8ab001710ff8a7c6bda0fb8 | 86 + .../83/e044245edbac001716b9ca6d5abb90bc | 368 + .../84/0021c94a7aad0017139dd5d73065d9ec | 355 + .../84/7015bce5f7ab001710ff8a7c6bda0fb8 | 87 + .../84/80036963c9ac001716b9ca6d5abb90bc | 605 + .../84/a05eab38e6ac001716b9ca6d5abb90bc | 248 + .../85/209583282cac001710ff8a7c6bda0fb8 | 88 + .../85/808711b72bac001710ff8a7c6bda0fb8 | 88 + .../85/808e9ecbf6ab001710ff8a7c6bda0fb8 | 109 + .../85/80f057855ca800171a8482560d609ceb | 227 + .../85/90ae4b9621ac001710ff8a7c6bda0fb8 | 287 + .../85/a0816d39a0ad0017181ed9113883eda9 | 52 + .../85/c09cd59465a800171a8482560d609ceb | 24 + .../85/f09ac541b3ad0017181ed9113883eda9 | 504 + .../86/4061804bb5ad0017181ed9113883eda9 | 522 + .../86/901545d3ceac001716b9ca6d5abb90bc | 216 + .../86/b0f69645e1ac001716b9ca6d5abb90bc | 187 + .../87/905c92e81bac001710ff8a7c6bda0fb8 | 23 + .../87/b04abcedceac001716b9ca6d5abb90bc | 221 + .../87/d06fb23ef8ab001710ff8a7c6bda0fb8 | 131 + .../87/d0de998023ac001710ff8a7c6bda0fb8 | 322 + .../87/e002367603ac001710ff8a7c6bda0fb8 | 76 + .../88/300f6db6a1ad0017181ed9113883eda9 | 51 + .../88/40c685021dac001710ff8a7c6bda0fb8 | 49 + .../88/a03701d4e4ac001716b9ca6d5abb90bc | 235 + .../88/c0bd27e169a800171a8482560d609ceb | 109 + .../88/f0cdb76ee4ac001716b9ca6d5abb90bc | 220 + .../89/10b16869e0ac001716b9ca6d5abb90bc | 149 + .../89/20a9116191ad0017181ed9113883eda9 | 503 + .../89/60482f9831ac001710ff8a7c6bda0fb8 | 337 + .../89/708832bd31ac001710ff8a7c6bda0fb8 | 338 + .../8a/60465a4069a800171a8482560d609ceb | 92 + .../8a/a0ae034ee2ac001716b9ca6d5abb90bc | 199 + .../8b/2028bc9e03ac001710ff8a7c6bda0fb8 | 77 + .../8b/f049864a2dac001710ff8a7c6bda0fb8 | 100 + .../8b/f080f2d269a800171a8482560d609ceb | 110 + .../8c/706d27faa0ad0017181ed9113883eda9 | 50 + .../8d/402cdc156aa800171a8482560d609ceb | 113 + .../8d/e0ba0b7bd4ac001716b9ca6d5abb90bc | 254 + .../8e/4072bac31bac001710ff8a7c6bda0fb8 | 26 + .../8e/40caa7ab5ba800171a8482560d609ceb | 196 + .../8e/603dcdc705ac001710ff8a7c6bda0fb8 | 92 + .../8e/c06f82a71aac001710ff8a7c6bda0fb8 | 13 + .../8f/70ff0f2bf7ab001710ff8a7c6bda0fb8 | 125 + .../8f/80a55cd41dac001710ff8a7c6bda0fb8 | 64 + .../8f/c0cb7c87cfac001716b9ca6d5abb90bc | 232 + .../9/10a786371dac001710ff8a7c6bda0fb8 | 54 + .../9/c03acb3d11ac001710ff8a7c6bda0fb8 | 71 + .../90/901e6400f8ab001710ff8a7c6bda0fb8 | 131 + .../91/600c98c7a1ad0017181ed9113883eda9 | 55 + .../92/a00bca565cac00171c63d91e40f02a62 | 234 + .../93/2080768c98ad0017181ed9113883eda9 | 36 + .../93/b0b2529ed9ac001716b9ca6d5abb90bc | 154 + .../93/e0abad5a03ac001710ff8a7c6bda0fb8 | 21 + .../93/f0f80f7ad8ac001716b9ca6d5abb90bc | 363 + .../94/20be01a706ac001710ff8a7c6bda0fb8 | 33 + .../94/80509c7cd5ac001716b9ca6d5abb90bc | 254 + .../94/c0c4843f89ad0017181ed9113883eda9 | 190 + .../94/c0e9a906f7ab001710ff8a7c6bda0fb8 | 115 + .../94/c0f36a7ae4ac001716b9ca6d5abb90bc | 220 + .../94/c0f5f1f904ac001710ff8a7c6bda0fb8 | 33 + .../95/106ce8205ca800171a8482560d609ceb | 199 + .../95/80feebb422ac001710ff8a7c6bda0fb8 | 217 + .../95/d0b13b4665a800171a8482560d609ceb | 67 + .../96/50660e361aac001710ff8a7c6bda0fb8 | 74 + .../96/70c7428c4fac001710ff8a7c6bda0fb8 | 243 + .../98/10bdd9f11cac001710ff8a7c6bda0fb8 | 45 + .../98/40b88e4fdeac001716b9ca6d5abb90bc | 183 + .../98/806ec5ec63a800171a8482560d609ceb | 21 + .../98/905f0aa3a3ad0017181ed9113883eda9 | 369 + .../98/c0cd5df358ac00171c63d91e40f02a62 | 151 + .../98/e0ddaa03e4ac001716b9ca6d5abb90bc | 209 + .../99/0038300d04ac001710ff8a7c6bda0fb8 | 70 + .../99/108ba746dbac001716b9ca6d5abb90bc | 88 + .../99/8003b4efb4ad0017181ed9113883eda9 | 187 + .../99/c0d1b349bcac001716b9ca6d5abb90bc | 604 + .../9a/5047c66c59ac00171c63d91e40f02a62 | 153 + .../9a/9020bf8105ac001710ff8a7c6bda0fb8 | 92 + .../9a/90e58c27dbac001716b9ca6d5abb90bc | 291 + .../9a/a0ca38a134ac001710ff8a7c6bda0fb8 | 338 + .../9a/c0c28d7a6aa800171a8482560d609ceb | 208 + .../9b/4006c59289ad0017181ed9113883eda9 | 188 + .../9b/607562f31bac001710ff8a7c6bda0fb8 | 28 + .../9b/700d3683e7ac001716b9ca6d5abb90bc | 250 + .../9b/a0c5a62123ac001710ff8a7c6bda0fb8 | 240 + .../9c/2087ada01fac001710ff8a7c6bda0fb8 | 35 + .../9c/701d65425ca800171a8482560d609ceb | 216 + .../9c/d0238e50c3ad0017181ed9113883eda9 | 494 + .../9c/d051dafe19ac001710ff8a7c6bda0fb8 | 74 + .../9d/3076b8ce68a800171a8482560d609ceb | 70 + .../9d/5049179dd5ac001716b9ca6d5abb90bc | 259 + .../9d/a0bc950e1eac001710ff8a7c6bda0fb8 | 27 + .../9e/e01bd697e1ac001716b9ca6d5abb90bc | 198 + .../9f/00cb17ba1dac001710ff8a7c6bda0fb8 | 65 + .../9f/5007a8de04ac001710ff8a7c6bda0fb8 | 28 + .../9f/d08d5d2106ac001710ff8a7c6bda0fb8 | 71 + .../a/30e9d046d4ac001716b9ca6d5abb90bc | 248 + .../a/50ae4bb952ac001710ff8a7c6bda0fb8 | 150 + .../a/a081b90164a800171a8482560d609ceb | 25 + .../a/c0ee8e47e4ac001716b9ca6d5abb90bc | 211 + .../a/d022dccc6da800171a8482560d609ceb | 35 + .../a/d05ac2d168a800171a8482560d609ceb | 71 + .../a/d0c43373c3ad0017181ed9113883eda9 | 492 + .../a0/308af7d8f8ab001710ff8a7c6bda0fb8 | 351 + .../a0/60b6f0541dac001710ff8a7c6bda0fb8 | 62 + .../a0/9069fa15c3ad0017181ed9113883eda9 | 495 + .../a0/e0c0b8d904ac001710ff8a7c6bda0fb8 | 88 + .../a1/003e3e7b4fac001710ff8a7c6bda0fb8 | 243 + .../a1/50041f4fcfac001716b9ca6d5abb90bc | 221 + .../a1/a07bc2d560ac00171ca19969f19d2325 | 248 + .../a1/b048dcf9f5ab001710ff8a7c6bda0fb8 | 112 + .../a1/d04b3b71a5ad0017181ed9113883eda9 | 56 + .../a2/20852d9403ac001710ff8a7c6bda0fb8 | 76 + .../a2/407e00c504ac001710ff8a7c6bda0fb8 | 88 + .../a2/5061348b26ac001710ff8a7c6bda0fb8 | 86 + .../a2/6056f2cb4fac001710ff8a7c6bda0fb8 | 140 + .../a2/f0d8feae65a800171a8482560d609ceb | 28 + .../a3/401ed82266ac00171f75fe2361138dfd | 236 + .../a3/a0965bb1e4ac001716b9ca6d5abb90bc | 223 + .../a3/e0491a3469a800171a8482560d609ceb | 91 + .../a4/10baef44f8ab001710ff8a7c6bda0fb8 | 135 + .../a4/10c20b3ec5ad0017181ed9113883eda9 | 521 + .../a5/2062891a03ac001710ff8a7c6bda0fb8 | 22 + .../a6/9039b1d7dfac001716b9ca6d5abb90bc | 187 + .../a7/00e268836da800171a8482560d609ceb | 42 + .../a7/30568a8fa0ad0017181ed9113883eda9 | 53 + .../a7/70b19de71dac001710ff8a7c6bda0fb8 | 68 + .../a7/70c03d9705ac001710ff8a7c6bda0fb8 | 92 + .../a7/a0902db74fac001710ff8a7c6bda0fb8 | 139 + .../a7/b0ba96e2d5ac001716b9ca6d5abb90bc | 269 + .../a8/4095613d68a800171a8482560d609ceb | 79 + .../a8/803e3c42d7ac001716b9ca6d5abb90bc | 279 + .../a8/a04a3bdee7ac001716b9ca6d5abb90bc | 43 + .../a8/b0d2e56a05ac001710ff8a7c6bda0fb8 | 87 + .../a8/c021eb1429ac001710ff8a7c6bda0fb8 | 99 + .../a8/d054b9f658ac00171c63d91e40f02a62 | 150 + .../a8/e00509dad7ac001716b9ca6d5abb90bc | 143 + .../a9/20cde3669fad0017181ed9113883eda9 | 33 + .../a9/40e9ecc6e6ac001716b9ca6d5abb90bc | 249 + .../a9/500e93c5d5ac001716b9ca6d5abb90bc | 265 + .../a9/50f9bfc666a800171a8482560d609ceb | 54 + .../a9/8036f5d929ad001713e0de43c08806fd | 188 + .../a9/b04660ada0ad0017181ed9113883eda9 | 61 + .../a9/c081497ec9ac001716b9ca6d5abb90bc | 355 + .../a9/c0ecdbb15ba800171a8482560d609ceb | 196 + .../aa/403bb575e1ac001716b9ca6d5abb90bc | 187 + .../aa/4083116e1dac001710ff8a7c6bda0fb8 | 63 + .../aa/70a5f893a3ad0017181ed9113883eda9 | 132 + .../ab/506f76f61fac001710ff8a7c6bda0fb8 | 87 + .../ab/70eb261ed8ac001716b9ca6d5abb90bc | 144 + .../ab/b09a89816da800171a8482560d609ceb | 35 + .../ac/30abf1fab4ad0017181ed9113883eda9 | 187 + .../ac/805f8d8db5ac001716b9ca6d5abb90bc | 355 + .../ac/a0ca04a35ba800171a8482560d609ceb | 196 + .../ad/40667fc262a800171a8482560d609ceb | 16 + .../ad/4083114ddeac001716b9ca6d5abb90bc | 179 + .../ad/70fcec3e27ac001710ff8a7c6bda0fb8 | 337 + .../ae/d0f13c3968a800171a8482560d609ceb | 82 + .../af/0088a7b1c9ac001716b9ca6d5abb90bc | 605 + .../af/308465da1bac001710ff8a7c6bda0fb8 | 26 + .../af/b087283700ac001710ff8a7c6bda0fb8 | 0 .../b/30f2f53008ac001710ff8a7c6bda0fb8 | 98 + .../b/700303e004ac001710ff8a7c6bda0fb8 | 32 + .../b/806d1b51b4ad0017181ed9113883eda9 | 524 + .../b/9082330aa0ad0017181ed9113883eda9 | 33 + .../b/c059b6a503ac001710ff8a7c6bda0fb8 | 77 + .../b0/70d2168260a800171a8482560d609ceb | 262 + .../b1/0051cea6d5ac001716b9ca6d5abb90bc | 263 + .../b1/504219b51dac001710ff8a7c6bda0fb8 | 63 + .../b1/a0c348acd9ac001716b9ca6d5abb90bc | 155 + .../b1/d074365422ac001710ff8a7c6bda0fb8 | 208 + .../b1/f0e13d3e5ca800171a8482560d609ceb | 207 + .../b2/204ab9a023ac001710ff8a7c6bda0fb8 | 316 + .../b2/b0190bb66aa800171a8482560d609ceb | 42 + .../b2/d07c71886da800171a8482560d609ceb | 42 + .../b3/201bd76bb3ad0017181ed9113883eda9 | 511 + .../b3/40a5f1e8b8ac001716b9ca6d5abb90bc | 603 + .../b3/80ea2f8de7ac001716b9ca6d5abb90bc | 36 + .../b3/90c2fce664a800171a8482560d609ceb | 50 + .../b4/30eed20e64a800171a8482560d609ceb | 27 + .../b4/d047883de1ac001716b9ca6d5abb90bc | 188 + .../b4/e0ac193f65a800171a8482560d609ceb | 64 + .../b5/40399e4003ac001710ff8a7c6bda0fb8 | 21 + .../b5/90f32a02b3ad0017181ed9113883eda9 | 502 + .../b5/c0de2650ccac001716b9ca6d5abb90bc | 199 + .../b6/80a6bd9bb6ad0017181ed9113883eda9 | 524 + .../b6/c08c15e6cbac001716b9ca6d5abb90bc | 193 + .../b7/30d491dd37ac001710ff8a7c6bda0fb8 | 100 + .../b7/708285e958ac00171c63d91e40f02a62 | 152 + .../b7/8099f407b8ac001716b9ca6d5abb90bc | 600 + .../b7/902ed8cecbad00171b48cedc605eece5 | 52 + .../b7/c0821a2b23ac001710ff8a7c6bda0fb8 | 234 + .../b8/00e80b69c5ad0017181ed9113883eda9 | 523 + .../b8/504716dd52ac001710ff8a7c6bda0fb8 | 150 + .../b8/601c95a8d7ac001716b9ca6d5abb90bc | 142 + .../b8/f048c24722ac001710ff8a7c6bda0fb8 | 208 + .../b9/10c10c5969a800171a8482560d609ceb | 112 + .../b9/50671825d4ac001716b9ca6d5abb90bc | 246 + .../b9/60d8a6a904ac001710ff8a7c6bda0fb8 | 91 + .../b9/705e0ff7e4ac001716b9ca6d5abb90bc | 234 + .../b9/70ab9f9451ac001710ff8a7c6bda0fb8 | 150 + .../b9/80aea1e1e4ac001716b9ca6d5abb90bc | 236 + .../b9/90260fc76da800171a8482560d609ceb | 42 + .../ba/509862f704ac001710ff8a7c6bda0fb8 | 33 + .../ba/607e6669b5ad0017181ed9113883eda9 | 523 + .../ba/60fa14012cac001710ff8a7c6bda0fb8 | 88 + .../ba/b0c8f6cb69a800171a8482560d609ceb | 115 + .../ba/d0d925c01bac001710ff8a7c6bda0fb8 | 27 + .../bb/20b3f7a44fac001710ff8a7c6bda0fb8 | 243 + .../bb/c0320e18e1ad00171536fea4e2c2e8be | 524 + .../bb/d05f6666dbac001716b9ca6d5abb90bc | 368 + .../bb/f05e24e42aad001713e0de43c08806fd | 191 + .../bc/e026666d03ac001710ff8a7c6bda0fb8 | 24 + .../bd/0092f91127ac001710ff8a7c6bda0fb8 | 327 + .../bd/10315d056ba800171a8482560d609ceb | 12 + .../bd/505d0d6126ac001710ff8a7c6bda0fb8 | 89 + .../bd/6035a9ef04ac001710ff8a7c6bda0fb8 | 32 + .../bd/606102f529ac001710ff8a7c6bda0fb8 | 100 + .../bd/b07a2029d7ac001716b9ca6d5abb90bc | 270 + .../bd/d0a4982c03ac001710ff8a7c6bda0fb8 | 21 + .../be/809095536aa800171a8482560d609ceb | 16 + .../be/f0170dbcb5ad0017181ed9113883eda9 | 523 + .../bf/707a9cdbc4ad0017181ed9113883eda9 | 509 + .../bf/80cced3d64a800171a8482560d609ceb | 27 + .../bf/90cc8e0637ac001710ff8a7c6bda0fb8 | 100 + .../bf/b0bad2914fac001710ff8a7c6bda0fb8 | 243 + .../c/00765baba0ad0017181ed9113883eda9 | 60 + .../c/e0546f7eabac001716b9ca6d5abb90bc | 155 + .../c0/100a598904ac001710ff8a7c6bda0fb8 | 86 + .../c0/4069778be0ac001716b9ca6d5abb90bc | 149 + .../c0/90fe4f592dac001710ff8a7c6bda0fb8 | 100 + .../c0/e06728ea05ac001710ff8a7c6bda0fb8 | 96 + .../c0/f05994565ca800171a8482560d609ceb | 223 + .../c1/1026fc199fad0017181ed9113883eda9 | 0 .../c1/409b84a8cfac001716b9ca6d5abb90bc | 232 + .../c1/606274b0cdac001716b9ca6d5abb90bc | 206 + .../c1/90f955d5e1ac001716b9ca6d5abb90bc | 148 + .../c1/b02fa6c104ac001710ff8a7c6bda0fb8 | 87 + .../c1/e00d35ec5fac00171ca19969f19d2325 | 237 + .../c2/0011b739e0ac001716b9ca6d5abb90bc | 148 + .../c2/50701c5f06ac001710ff8a7c6bda0fb8 | 120 + .../c2/805d9d5d1eac001710ff8a7c6bda0fb8 | 28 + .../c2/b069017f11ac001710ff8a7c6bda0fb8 | 27 + .../c2/e0564af81dac001710ff8a7c6bda0fb8 | 78 + .../c2/e0e90fc76da800171a8482560d609ceb | 42 + .../c3/309944b9a1ad0017181ed9113883eda9 | 56 + .../c3/4080f5b2d3ac001716b9ca6d5abb90bc | 242 + .../c3/b06de7a0e1ac001716b9ca6d5abb90bc | 199 + .../c3/e05862c8afad0017181ed9113883eda9 | 502 + .../c4/20419ed021ac001710ff8a7c6bda0fb8 | 50 + .../c4/70c215f856ac00171c63d91e40f02a62 | 152 + .../c4/c01a91c731ac001710ff8a7c6bda0fb8 | 338 + .../c5/5072b3566aa800171a8482560d609ceb | 99 + .../c6/000d73ae31ac001710ff8a7c6bda0fb8 | 338 + .../c6/005f226ed4ac001716b9ca6d5abb90bc | 254 + .../c6/30d1f210f7ab001710ff8a7c6bda0fb8 | 120 + .../c6/9002149285ad0017181ed9113883eda9 | 605 + .../c7/303bbd9222ac001710ff8a7c6bda0fb8 | 208 + .../c7/306b6cb061ac00171ca19969f19d2325 | 155 + .../c7/50f07caf6aa800171a8482560d609ceb | 35 + .../c8/30cbde246aa800171a8482560d609ceb | 104 + .../c8/b00d77bc6da800171a8482560d609ceb | 56 + .../c9/20ed8c17d6ac001716b9ca6d5abb90bc | 277 + .../ca/f04c3ce267a800171a8482560d609ceb | 77 + .../cb/20fd1e9c05ac001710ff8a7c6bda0fb8 | 92 + .../cb/500f92514fac001710ff8a7c6bda0fb8 | 132 + .../cb/70aced995ba800171a8482560d609ceb | 184 + .../cb/80f3ada6a0ad0017181ed9113883eda9 | 60 + .../cb/a053859df4ab001710ff8a7c6bda0fb8 | 246 + .../cb/b00533b9e0ac001716b9ca6d5abb90bc | 151 + .../cb/f0426ab665a800171a8482560d609ceb | 33 + .../cc/20526809d6ac001716b9ca6d5abb90bc | 274 + .../cc/908cb5595ba800171a8482560d609ceb | 183 + .../cc/b06dd99a19ac001710ff8a7c6bda0fb8 | 73 + .../cd/a005d14c1fac001710ff8a7c6bda0fb8 | 84 + .../cd/c003f191e1ac001716b9ca6d5abb90bc | 197 + .../ce/10663a33dbac001716b9ca6d5abb90bc | 605 + .../ce/80357b80dfad00171536fea4e2c2e8be | 523 + .../cf/407ed953c3ad0017181ed9113883eda9 | 493 + .../d0/4051a3aee0ac001716b9ca6d5abb90bc | 150 + .../d0/605e9939b5ac001716b9ca6d5abb90bc | 355 + .../d0/80a9ccb923ac001710ff8a7c6bda0fb8 | 320 + .../d0/902a116bd8ac001716b9ca6d5abb90bc | 363 + .../d0/f01bbc2423ac001710ff8a7c6bda0fb8 | 234 + .../d1/206c13f56aa800171a8482560d609ceb | 12 + .../d1/c08fa1f5f6ab001710ff8a7c6bda0fb8 | 115 + .../d1/e03c398669a800171a8482560d609ceb | 99 + .../d2/3038caabb2ad0017181ed9113883eda9 | 502 + .../d2/40fe2bd9d5ac001716b9ca6d5abb90bc | 265 + .../d2/7022b67821ac001710ff8a7c6bda0fb8 | 290 + .../d2/70c87e2e6aa800171a8482560d609ceb | 104 + .../d3/20d30dea64a800171a8482560d609ceb | 58 + .../d3/302bfa4709ac001710ff8a7c6bda0fb8 | 100 + .../d3/403ff763c5ad0017181ed9113883eda9 | 522 + .../d3/f093a187a2ad0017181ed9113883eda9 | 79 + .../d4/40c49ebde0ac001716b9ca6d5abb90bc | 150 + .../d4/d0f62a8bf7ab001710ff8a7c6bda0fb8 | 83 + .../d5/0093b68423ac001710ff8a7c6bda0fb8 | 322 + .../d5/20908afcb3ad0017181ed9113883eda9 | 515 + .../d5/30a55330acac001716b9ca6d5abb90bc | 155 + .../d5/40cbe317ccac001716b9ca6d5abb90bc | 193 + .../d5/50968f281cac001710ff8a7c6bda0fb8 | 32 + .../d6/b09d47221cac001710ff8a7c6bda0fb8 | 28 + .../d7/004317ff64a800171a8482560d609ceb | 59 + .../d7/60d73d281dac001710ff8a7c6bda0fb8 | 53 + .../d7/70151736b5ac001716b9ca6d5abb90bc | 355 + .../d7/f0ad1fce60ac00171ca19969f19d2325 | 248 + .../d8/1085b7f621ac001710ff8a7c6bda0fb8 | 211 + .../d8/50a569836da800171a8482560d609ceb | 42 + .../d8/50f176e553ac001710ff8a7c6bda0fb8 | 151 + .../d8/f00b8baa06ac001710ff8a7c6bda0fb8 | 34 + .../d8/f05963bc23ac001710ff8a7c6bda0fb8 | 324 + .../d9/508ad9ba6da800171a8482560d609ceb | 56 + .../d9/7094428fc4ad0017181ed9113883eda9 | 495 + .../d9/b057cfe669a800171a8482560d609ceb | 113 + .../d9/c009708fd7ac001716b9ca6d5abb90bc | 121 + .../d9/d0c9f45526ac001710ff8a7c6bda0fb8 | 89 + .../da/40ae3979b9ac001716b9ca6d5abb90bc | 604 + .../da/6081ae6d5ca800171a8482560d609ceb | 225 + .../da/c0eefdc32aad001713e0de43c08806fd | 189 + .../db/d05d7acd7fad0017181ed9113883eda9 | 191 + .../dc/904dedc619ac001710ff8a7c6bda0fb8 | 74 + .../dc/90f0bcbff4ab001710ff8a7c6bda0fb8 | 27 + .../dd/00afb2566aa800171a8482560d609ceb | 99 + .../dd/206f8ef4c4ad0017181ed9113883eda9 | 516 + .../dd/d0aca700e0ac001716b9ca6d5abb90bc | 188 + .../de/305d803423ac001710ff8a7c6bda0fb8 | 233 + .../de/400b4c649fad0017181ed9113883eda9 | 27 + .../de/d0102ea37aad0017139dd5d73065d9ec | 192 + .../df/20d826b6d5ac001716b9ca6d5abb90bc | 265 + .../df/90ce9028bbac001716b9ca6d5abb90bc | 604 + .../df/e05aea31e5ac001716b9ca6d5abb90bc | 239 + .../df/f0a11525b5ad0017181ed9113883eda9 | 518 + .../e/609b46bf31ac001710ff8a7c6bda0fb8 | 338 + .../e/700b1efb5ba800171a8482560d609ceb | 199 + .../e0/8092913d24ac001710ff8a7c6bda0fb8 | 328 + .../e0/a03492f16aa800171a8482560d609ceb | 12 + .../e0/f025dbc769a800171a8482560d609ceb | 115 + .../e1/80a8e68d04ac001710ff8a7c6bda0fb8 | 86 + .../e2/20032dc67fad0017181ed9113883eda9 | 191 + .../e2/5020156065a800171a8482560d609ceb | 67 + .../e2/70b70a8cc3ad0017181ed9113883eda9 | 493 + .../e2/f0425b8821ac001710ff8a7c6bda0fb8 | 287 + .../e4/4059f899d9ac001716b9ca6d5abb90bc | 155 + .../e5/203d7a7234ac001710ff8a7c6bda0fb8 | 338 + .../e5/9061c62a1eac001710ff8a7c6bda0fb8 | 27 + .../e5/f0935d6167a800171a8482560d609ceb | 66 + .../e6/207e4997a3ad0017181ed9113883eda9 | 218 + .../e6/e08d2b131dac001710ff8a7c6bda0fb8 | 52 + .../e7/a0e0d9edd5ac001716b9ca6d5abb90bc | 270 + .../e8/20b1cad36ca800171a8482560d609ceb | 42 + .../e8/70971d3ce5ac001716b9ca6d5abb90bc | 243 + .../e8/b0ddd35cf7ab001710ff8a7c6bda0fb8 | 129 + .../e9/208ee49ef7ab001710ff8a7c6bda0fb8 | 83 + .../e9/4013f50ee5ac001716b9ca6d5abb90bc | 236 + .../e9/90cd219a05ac001710ff8a7c6bda0fb8 | 92 + .../e9/a022a50403ac001710ff8a7c6bda0fb8 | 15 + .../e9/d006eeec21ac001710ff8a7c6bda0fb8 | 211 + .../e9/d0ff1d71a5ad0017181ed9113883eda9 | 42 + .../ea/60ecdf1d6fa800171a8482560d609ceb | 103 + .../ea/9025de20bfac001716b9ca6d5abb90bc | 604 + .../eb/2021a16626ac001710ff8a7c6bda0fb8 | 87 + .../eb/80166cdc03ac001710ff8a7c6bda0fb8 | 77 + .../eb/b0e8f93623ac001710ff8a7c6bda0fb8 | 232 + .../eb/c06725bb6aa800171a8482560d609ceb | 42 + .../eb/d0940911b8ac001716b9ca6d5abb90bc | 193 + .../ec/00a2d3dd6fa800171a8482560d609ceb | 82 + .../ec/803ad67e6da800171a8482560d609ceb | 42 + .../ec/80b1fc5504ac001710ff8a7c6bda0fb8 | 79 + .../ec/b0b90ce869a800171a8482560d609ceb | 113 + .../ed/d0307bf0c4ad0017181ed9113883eda9 | 516 + .../ed/e076043e66a800171a8482560d609ceb | 50 + .../ee/2060f2c92dac001710ff8a7c6bda0fb8 | 100 + .../ee/a0e97951e2ac001716b9ca6d5abb90bc | 200 + .../ee/e063a0e405ac001710ff8a7c6bda0fb8 | 96 + .../f/007161e403ac001710ff8a7c6bda0fb8 | 70 + .../f/80cfa981e4ac001716b9ca6d5abb90bc | 220 + .../f0/b00e1d621dac001710ff8a7c6bda0fb8 | 62 + .../f1/40534e4de0ac001716b9ca6d5abb90bc | 148 + .../f1/4058227a03ac001710ff8a7c6bda0fb8 | 76 + .../f1/a0ccf39ca2ad0017181ed9113883eda9 | 102 + .../f1/f0b1078018ac001710ff8a7c6bda0fb8 | 0 .../f2/00fb9210c5ad0017181ed9113883eda9 | 516 + .../f2/205b62d228ac001710ff8a7c6bda0fb8 | 99 + .../f2/40de80ad04ac001710ff8a7c6bda0fb8 | 91 + .../f2/7032eb2669a800171a8482560d609ceb | 83 + .../f2/70e487be1fac001710ff8a7c6bda0fb8 | 39 + .../f3/f0a22d5cb5ad0017181ed9113883eda9 | 522 + .../f4/601a0f24e4ac001716b9ca6d5abb90bc | 210 + .../f4/f0223ffad6ac001716b9ca6d5abb90bc | 274 + .../f4/f05a287b21ac001710ff8a7c6bda0fb8 | 289 + .../f5/8025f0b71cac001710ff8a7c6bda0fb8 | 39 + .../f5/d00d8ca969a800171a8482560d609ceb | 113 + .../f6/305344955ca800171a8482560d609ceb | 229 + .../f6/6074ea1c65a800171a8482560d609ceb | 61 + .../f6/70c6c0fe05ac001710ff8a7c6bda0fb8 | 95 + .../f6/80457721b5ad0017181ed9113883eda9 | 515 + .../f7/40b0cfa5d6ac001716b9ca6d5abb90bc | 288 + .../f7/603bf12c1fac001710ff8a7c6bda0fb8 | 28 + .../f7/702d21411aac001710ff8a7c6bda0fb8 | 76 + .../f7/70e1c01c67a800171a8482560d609ceb | 56 + .../f8/60ddb5c326ac001710ff8a7c6bda0fb8 | 234 + .../f8/70ac59ef1dac001710ff8a7c6bda0fb8 | 73 + .../f8/e08fc2e1d7ac001716b9ca6d5abb90bc | 144 + .../fa/1096727405ac001710ff8a7c6bda0fb8 | 87 + .../fb/30fc8d1b66a800171a8482560d609ceb | 45 + .../fb/e0a01d43f2ab001710ff8a7c6bda0fb8 | 115 + .../fc/10d69239b2ac001716b9ca6d5abb90bc | 599 + .../fc/10f958adb3ad0017181ed9113883eda9 | 514 + .../fc/a0fc077523ac001710ff8a7c6bda0fb8 | 305 + .../fd/a0c92a2bd7ac001716b9ca6d5abb90bc | 291 + .../fe/502a91841bac001710ff8a7c6bda0fb8 | 22 + .../fe/e0de531569a800171a8482560d609ceb | 82 + .../ff/7095ccf204ac001710ff8a7c6bda0fb8 | 32 + .../.indexes/properties.index | Bin 0 -> 80 bytes .../RemoteSystemsTempFiles/.markers.snap | Bin 0 -> 48 bytes .../RemoteSystemsTempFiles/.syncinfo.snap | Bin 0 -> 48 bytes .../GitProjectData.properties | 3 + .../judt/.indexes/e4/9d/9c/history.index | Bin 0 -> 65 bytes .../.projects/judt/.indexes/properties.index | Bin 0 -> 80 bytes .../.projects/judt/.markers | Bin 6182 -> 5574 bytes .../.projects/judt/.markers.snap | Bin 0 -> 4862 bytes .../.projects/judt/.syncinfo.snap | Bin 0 -> 48 bytes .../GitProjectData.properties | 3 + .../.root/.indexes/properties.index | Bin 203 -> 203 bytes .../.root/.markers.snap | Bin 0 -> 75 bytes .../org.eclipse.core.resources/.root/6.tree | Bin 0 -> 11079 bytes .../.safetable/org.eclipse.core.resources | Bin 1486 -> 3115 bytes .../org.eclipse.core.resources/6.snap | Bin 0 -> 795 bytes .../.settings/org.eclipse.debug.ui.prefs | 2 +- .../.settings/org.eclipse.egit.core.prefs | 3 + .../.settings/org.eclipse.jdt.ui.prefs | 1 + ....eclipse.recommenders.completion.rcp.prefs | 2 + .../.settings/org.eclipse.ui.ide.prefs | 2 +- .../.settings/org.eclipse.ui.workbench.prefs | 40 +- .../.settings/org.eclipse.wst.jsdt.ui.prefs | 2 +- .../.launches/TestClient.launch | 7 +- .../.launches/TestRecFiles.launch | 11 + .../.launches/TestSendFiles.launch | 11 + .../.launches/TestServer.launch | 11 + .../org.eclipse.debug.ui/dialog_settings.xml | Bin 652 -> 1052 bytes .../launchConfigurationHistory.xml | 11 +- .../org.eclipse.e4.workbench/workbench.xmi | 5213 +++---- .../server-config.json | 4 +- .../org.eclipse.jdt.core/1805218701.index | Bin 77082 -> 86362 bytes .../assumedExternalFilesCache | Bin 812 -> 4 bytes .../externalLibsTimeStamps | Bin 956 -> 956 bytes .../org.eclipse.jdt.core/savedIndexNames.txt | 2 +- .../dialog_settings.xml | 6 - .../org.eclipse.jdt.launching/.install.xml | 2 +- .../org.eclipse.jdt.ui/dialog_settings.xml | 64 - .../org.eclipse.jdt.ui/jdt-images/0.png | Bin 0 -> 534 bytes .../org.eclipse.jdt.ui/jdt-images/1.png | Bin 0 -> 345 bytes .../org.eclipse.jdt.ui/jdt-images/10.png | Bin 0 -> 283 bytes .../org.eclipse.jdt.ui/jdt-images/11.png | Bin 0 -> 319 bytes .../org.eclipse.jdt.ui/jdt-images/12.png | Bin 0 -> 310 bytes .../org.eclipse.jdt.ui/jdt-images/13.png | Bin 0 -> 537 bytes .../org.eclipse.jdt.ui/jdt-images/14.png | Bin 0 -> 184 bytes .../org.eclipse.jdt.ui/jdt-images/15.png | Bin 0 -> 563 bytes .../org.eclipse.jdt.ui/jdt-images/2.png | Bin 0 -> 294 bytes .../org.eclipse.jdt.ui/jdt-images/3.png | Bin 0 -> 307 bytes .../org.eclipse.jdt.ui/jdt-images/4.png | Bin 0 -> 412 bytes .../org.eclipse.jdt.ui/jdt-images/5.png | Bin 0 -> 452 bytes .../org.eclipse.jdt.ui/jdt-images/6.png | Bin 0 -> 217 bytes .../org.eclipse.jdt.ui/jdt-images/7.png | Bin 0 -> 411 bytes .../org.eclipse.jdt.ui/jdt-images/8.png | Bin 0 -> 635 bytes .../org.eclipse.jdt.ui/jdt-images/9.png | Bin 0 -> 333 bytes .../judt/2017/10/41/refactorings.history | 3 + .../judt/2017/10/41/refactorings.index | 4 + .../dialog_settings.xml | Bin 6879 -> 7324 bytes .../0.log | 428 + .../logback.1.8.1.20170728-1531.xml | 43 + .../.cache/clean-cache.properties | 2 +- .../.local_targets/1507647106718.target | 12 + .../.local_targets/1507647150848.target | 12 + .../.local_targets/1507647262388.target | 12 + .../.local_targets/1507647315540.target | 12 + .../.local_targets/1507647349336.target | 12 + .../.local_targets/1507648147331.target | 12 + .../SavedExternalPluginList.txt | 1001 ++ .../org.eclipse.ui.ide/dialog_settings.xml | 26 + .../dialog_settings.xml | 21 + .../dialog_settings.xml | 19 +- .../org.eclipse.ui.workbench/workingsets.xml | 1 + .../externalLibsTimeStamps | Bin 483 -> 483 bytes .metadata/version.ini | 4 +- .../identified-project-coordinates.json | 2 +- .recommenders/caches/manual-mappings.json | Bin 2 -> 2 bytes .../_8.fdt | Bin 0 -> 5021699 bytes .../_8.fdx | Bin 0 -> 92028 bytes .../_8.fnm | 3 + .../_8.frq | 1109 ++ .../_8.nrm | 1 + .../_8.prx | Bin 0 -> 129208 bytes .../_8.tii | Bin 0 -> 21142 bytes .../_8.tis | Bin 0 -> 1324039 bytes .../segments.gen | Bin 0 -> 20 bytes .../segments_9 | Bin 0 -> 244 bytes Config.xml | 6 + Server.bat | 1 + Server.jar | Bin 0 -> 152588 bytes judt/bin/.gitignore | 4 + judt/bin/Config.xml | 6 + judt/bin/Test/TestClient.class | Bin 1182 -> 1373 bytes judt/bin/Test/TestServer.class | Bin 1105 -> 1097 bytes judt/bin/judp/ApplicationCode.class | Bin 4075 -> 4072 bytes judt/bin/judp/judpClient.class | Bin 3838 -> 4703 bytes judt/bin/judp/judpServer$1.class | Bin 1375 -> 1424 bytes judt/bin/judp/judpServer.class | Bin 3702 -> 3906 bytes judt/bin/judp/judpSocket.class | Bin 4893 -> 5871 bytes judt/bin/udt/ClientSession.class | Bin 4727 -> 5042 bytes judt/bin/udt/ServerSession.class | Bin 4948 -> 4948 bytes judt/bin/udt/UDPEndPoint.class | Bin 8377 -> 8500 bytes judt/bin/udt/UDTClient.class | Bin 4826 -> 5511 bytes judt/bin/udt/UDTInputStream$AppData.class | Bin 1750 -> 1750 bytes judt/bin/udt/UDTInputStream.class | Bin 3683 -> 4031 bytes judt/bin/udt/UDTReceiver$1.class | Bin 1832 -> 1832 bytes judt/bin/udt/UDTReceiver.class | Bin 13921 -> 13921 bytes judt/bin/udt/UDTSender$1.class | Bin 1667 -> 1667 bytes judt/bin/udt/UDTSender.class | Bin 13118 -> 13543 bytes judt/bin/udt/UDTSocket.class | Bin 4836 -> 4836 bytes judt/bin/udt/packets/Acknowledgment2.class | Bin 1299 -> 1380 bytes judt/bin/udt/util/ReceiveBuffer.class | Bin 3428 -> 4908 bytes judt/src/Test/TestClient.java | 8 +- judt/src/Test/TestServer.java | 8 +- judt/src/judp/ApplicationCode.java | 2 +- judt/src/judp/DataStruct.java | 88 + judt/src/judp/PackagetCombin.java | 55 + judt/src/judp/PackagetSub.java | 100 + judt/src/judp/SocketControls.java | 134 + judt/src/judp/SocketReference.java | 34 + judt/src/judp/judpClient.java | 154 +- judt/src/judp/judpGroupSocket.java | 90 + judt/src/judp/judpServer.java | 68 +- judt/src/judp/judpSocket.java | 335 +- judt/src/judp/judpSocketManager.java | 116 + judt/src/net/File/FileMonitor.java | 16 + judt/src/net/File/FilesWatch.java | 99 + judt/src/net/File/PackagetCharSet.java | 12 + judt/src/net/File/ReadXml.java | 104 + judt/src/net/File/RecviceFiles.java | 251 + judt/src/net/File/SendFiles.java | 150 + judt/src/net/File/TestRecFiles.java | 43 + judt/src/net/File/TestSendFiles.java | 52 + judt/src/udt/ClientSession.java | 6 +- judt/src/udt/ServerSession.java | 2 +- judt/src/udt/UDPEndPoint.java | 22 +- judt/src/udt/UDTClient.java | 75 +- judt/src/udt/UDTCongestionControl.java | 2 +- judt/src/udt/UDTInputStream.java | 42 +- judt/src/udt/UDTReceiver.java | 13 +- judt/src/udt/UDTSender.java | 57 +- judt/src/udt/UDTSession.java | 2 +- judt/src/udt/UDTSocket.java | 3 + judt/src/udt/packets/Acknowledgment2.java | 7 +- judt/src/udt/util/ReceiveBuffer.java | 156 +- recFile.bat | 1 + recFile.jar | Bin 0 -> 160970 bytes sendFile.bat | 1 + sendFile.jar | Bin 0 -> 153757 bytes sendFiles.jar | Bin 0 -> 153757 bytes ...4\346\226\260\350\257\264\346\230\216.txt" | 25 +- 931 files changed, 165752 insertions(+), 6786 deletions(-) create mode 100644 .metadata/.bak_0.log create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/0/209a8eaa21ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/0/c0b151e22dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/0/e03d304ed7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1/80f6654c19ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1/d00788f456ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1/e085ced59aad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1/f0f3e82c6fa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/10/00c09b1e59ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/10/709e69df58ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/10/d0aa129d98ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/10/f0565a8d18ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/12/90ddb49ea2ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/12/e051f64398ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/13/10bc98feb5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/13/e0517759cbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/14/0005620c24ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/14/b0bb513ec8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/14/c081423d1cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/15/503d09ac4fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/16/0013e7ed04ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/16/109c5e88d6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/16/406135d6daac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/16/c058bb4b62a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/16/d0bf190435ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/17/10936cbe05ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/17/30f8db4bd8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/17/807fbc93e2ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/17/80cd43731aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/17/a0ce86b02dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/17/c0591a57b5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/18/006c2690d8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/18/307f6ce864a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/18/6065932703ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/18/c05c601f6da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/18/f0e7afc269a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/19/00d683551aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/19/40df30479fad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/19/6063b7c5ceac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/19/60d4a2c04fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/19/c03f59b4f3ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/19/d056ace51fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1a/f0fb59a4a1ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1b/201f78bc6da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1c/404d73a415ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1c/509f6ba4c9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1d/d09bb2d219ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1d/e04931bbe4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1e/6080d540c8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1e/c080de4460ac00171ca19969f19d2325 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1e/e06c053c27ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1f/20acb57d69a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1f/70a02b246da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1f/b0635746e5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1f/c0c69f405ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/1f/e004bd9ee7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2/b0e3a7446ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/20/4057838a1aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/20/602e70256da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/20/c06bb2f50eac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/21/10bf9d62dbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/21/b0314608c5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/21/f0f57f2ec5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/22/3024d0d16da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/22/40a8ff391bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/22/70ca7fc634ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/22/8070220c0fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/23/00e997b8a2ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/23/301509806da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/23/a089455d57ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/23/d00f297c26ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/24/40719255f4ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/24/5048587004ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/24/70abceb2e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/24/d09c215ae5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/25/c0e0b2fbe2ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/26/204e38905bac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/26/90b7a18162a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/26/c0f91e9d5ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/27/001fcd525dac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/27/6089d24d1aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/27/a02fb0af2bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/27/b07f5b0fb5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/27/f03094536aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/28/20611a6ec3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/28/b08c10a81fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/29/306a36aed6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2a/507d3e2903ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2a/b06d26c4cfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2a/d05059bbcfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2b/00218dfa88ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2b/6049060569a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2b/b0ae6971bcac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2c/00da54ff0eac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2c/30197d17d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2c/801fec2f59ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2c/b041f93e67a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2c/d0baafa565a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2d/10bf61d937ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2d/6073c07321ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2d/60a67df369a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2d/60cfdf2409ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2e/200d3c4164a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2e/30535d40c5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2e/4043e9f84fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2e/603775eeb3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2e/6047b62203ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2e/b08f394dc5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2e/c0aa731ac5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2e/f0a141dda3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2f/1088bc2468a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2f/2054ba4000ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2f/20ad410dc5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2f/804aa08d21ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3/60d321ea61ac00171ca19969f19d2325 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3/d0bbd534b5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/30/4057ad45c5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/30/a07a6f8a9aad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/30/c0f68a50d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/30/f0d85be699ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/31/0079a8fd4fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/31/106f933126ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/32/50142e9c31ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/33/30bcc157d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/33/703f445cc9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/33/b04561b206ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/34/b06540c026ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/35/204ce0dff7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/35/8092462f1eac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/36/106b6f256da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/36/406a1f2526ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/36/60ac64f0e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/36/d0590bba1bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/37/204743b36aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/37/a01fdf541cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/38/101a00e86aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/38/c0d1e01c26ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/39/30cdd9d35aac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/39/803bf78dceac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/39/f089629426ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3a/50db850527ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3a/600fb8d2a0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3a/c0bd03d4e6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3b/0009e5c7a3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3b/20158b335ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3c/20d0ca0806ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3d/a0e3d71e22ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3d/b0e4032f6fa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3d/c0b81a6bdeac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3d/d0dec61a6aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3e/105906a604ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3e/10c01b9bd8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3e/90c8f6fe1bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3f/0095c3b32bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3f/00c3b2bf97ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3f/20ae3effb7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3f/90252382e1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3f/a091f71264a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3f/d057016d64a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4/30a058a9e7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4/40be8a05e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4/60fff865d8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/40/10dbf0de4fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/40/70a06d54ddac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/40/a02a6e9dcfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/40/a05bab671aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/40/c0b85c6bf7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/41/f064f58963ac00171f75fe2361138dfd create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/41/f07d59bd1cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/42/101d91fd26ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/42/3010ed2dd2ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/42/e050c8c64fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/42/f048fd99a2ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/43/60189468a3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/43/80c63bcb21ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/44/00022a6de4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/44/10c21fc9d6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/44/c0e041dbe7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/44/e0948e82cead00171536fea4e2c2e8be create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/44/e0b7669b5ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/45/30c1c047b5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/45/80fb200424ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/45/b017204bd7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/46/60c6b52059ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/46/e0878eb7f8ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/47/007297c0b8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/47/d00bbfdca0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/48/d0a3f354a2ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/48/d0b6053b5ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/49/3039da0c69a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/49/607bc94804ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4a/80cbba742aad001713e0de43c08806fd create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4a/d05deaacb8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4a/d0c629a9cdac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4b/a035f5deb4ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4b/a0ad7bad60a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4c/00556ecf13ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4c/f007c03509ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4c/f03eaf6868a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4c/f0982c98e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4d/400ac46406ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4d/b0a68230f7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4e/30bcb47629ad001713e0de43c08806fd create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4e/503da3aa52ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4e/903b8e7ad6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4e/b0d52a15e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4f/200a00ac60a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4f/305dcf6953ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/4f/b0a7c36b64a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/50/002264c122ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/50/10970a0ca1ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/50/300b00e08ead0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/50/6044e0b534ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/50/607944715ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/50/80d9f8332aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/50/c03beacccfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/51/20a6e040d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/51/30d701b321ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/51/900a2db5a0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/51/c06ec8a7a1ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/52/60fcfcdf2aad001713e0de43c08806fd create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/52/80a9f5a752ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/52/a0e88386d6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/53/60e8bdb026ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/53/c0fa7ce21dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/53/e0cf12f56aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/54/d0d788fe58ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/54/f09c3717a1ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/55/2001542903ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/55/e05f7dc334ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/56/30539028d8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/56/40e91a0269a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/56/509c645db5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/57/60df03ff04ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/57/70fe88816da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/57/c01e4b7e21ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/57/c030fc7309ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/57/d0125e1f6da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/58/50cfdaa722ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/58/80a5207c6fa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/59/2091b446e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5a/10ee44b7a0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5a/30d29f9969a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5a/b091bc44e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5a/c0e40d3ea0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5a/c0e9c48ee4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5b/b0bdcfc2d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5c/20504804c5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5d/6043da1d1aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5d/70679366d4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5e/205e2eb706ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5e/30073a3d25ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5e/60083557deac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5e/80cf2f975ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5f/10f8023268a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5f/d03f8ec3e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6/40f9d9b9ceac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/60/0049134464a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/60/2023350a64a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/60/30e12f8c69a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/60/b0bfd1a019ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/61/109c41f905ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/61/60416b18e5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/61/a02c15f303ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/62/d0dc45525ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/63/1027745f23ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/63/2084e14ee5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/63/40a19ee8ceac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/63/f0ff4653cbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/64/00f0eed5f6ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/64/d0b50df3b4ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/65/20253f0eb3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/65/50bfc894a6ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/65/c0b5f764b9ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/65/d0bc506103ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/65/e0d96e5a1eac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/66/10f59fb9a0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/66/704245e5e1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/66/804c48ac2bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/66/f01f9db921ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/66/f0ac4e11e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/67/1081b1f8b5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/67/60dc22d413ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/67/80be36cff8ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/67/c071fbe65ea800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/67/d0d5236bf4ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/69/b06da8a2d8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/69/d0e5e1f3a0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6a/40965eabcfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6a/80d7e50364a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6b/00bc254e26ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6c/301bb18ff7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6d/408eaf421dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6d/a0cd93471cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6d/f04b670427ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6e/001449b561ac00171ca19969f19d2325 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6e/40913b1af8ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6e/c0a030dfdfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6e/d0f5ffe8f7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6f/a0409b8eb3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6f/c03e69c56da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7/509a29f366a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7/a0002b2d5ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7/d084703024ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/70/201ef600e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/70/907af0871eac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/71/3084b6db9aad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/71/5038a5acd5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/71/604351d567a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/71/60903e2466a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/71/80add8d6d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/71/b04f3e4167a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/72/10921d306fa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/72/a0a4851566a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/72/f02fa8b892ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/73/00abaea82bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/73/a037d3e934ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/73/d0e9d0895fac00171ca19969f19d2325 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/74/3091ac6c7fad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/74/70995f1f6da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/74/a0ba2744b2ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/74/b065917426ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/75/0052421d5da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/75/00cbed535ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/75/70afe12ddbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/75/a0430dbae1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/75/b0a223eb03ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/76/5036ee8cd6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/77/403c36a21aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/78/10e15310c3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/78/8067edbee4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/78/9086b899d8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/78/b07ba83069a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/79/6084a52a24ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/79/e07207b3d9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7a/60f5446d26ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7a/d078325404ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7c/00baf1751bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7c/708d70c31aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7c/f009da97d5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7d/50c2175e68a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7d/50df241c27ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7d/604ba6846aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7d/90850181b8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7d/a00a34b931ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7d/b0fe5132d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7d/d043da1809ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7d/f014ead31aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7e/006d75ddffab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7e/401863511cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7e/b067998b05ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7f/3056569822ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7f/40c53669d8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7f/60f67dd3feab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7f/b07dd0961bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/80/105d7f665ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/80/d030786d1aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/81/20dcb587daac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/81/500e2b00d6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/82/0096696f19ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/82/209d88b969a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/82/50bd4a31d6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/82/7042778204ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/82/801757f229ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/82/8060528c6da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/83/30fc38d25fac00171ca19969f19d2325 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/83/d01fa7f1d6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/83/d02d0d08f8ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/83/e044245edbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/84/0021c94a7aad0017139dd5d73065d9ec create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/84/7015bce5f7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/84/80036963c9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/84/a05eab38e6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/209583282cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/808711b72bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/808e9ecbf6ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/80f057855ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/90ae4b9621ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/a0816d39a0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/c09cd59465a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/f09ac541b3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/86/4061804bb5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/86/901545d3ceac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/86/b0f69645e1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/87/905c92e81bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/87/b04abcedceac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/87/d06fb23ef8ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/87/d0de998023ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/87/e002367603ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/88/300f6db6a1ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/88/40c685021dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/88/a03701d4e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/88/c0bd27e169a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/88/f0cdb76ee4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/89/10b16869e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/89/20a9116191ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/89/60482f9831ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/89/708832bd31ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8a/60465a4069a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8a/a0ae034ee2ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8b/2028bc9e03ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8b/f049864a2dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8b/f080f2d269a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8c/706d27faa0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8d/402cdc156aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8d/e0ba0b7bd4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8e/4072bac31bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8e/40caa7ab5ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8e/603dcdc705ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8e/c06f82a71aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8f/70ff0f2bf7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8f/80a55cd41dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/8f/c0cb7c87cfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9/10a786371dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9/c03acb3d11ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/90/901e6400f8ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/91/600c98c7a1ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/92/a00bca565cac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/93/2080768c98ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/93/b0b2529ed9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/93/e0abad5a03ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/93/f0f80f7ad8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/94/20be01a706ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/94/80509c7cd5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/94/c0c4843f89ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/94/c0e9a906f7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/94/c0f36a7ae4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/94/c0f5f1f904ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/95/106ce8205ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/95/80feebb422ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/95/d0b13b4665a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/96/50660e361aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/96/70c7428c4fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/98/10bdd9f11cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/98/40b88e4fdeac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/98/806ec5ec63a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/98/905f0aa3a3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/98/c0cd5df358ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/98/e0ddaa03e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/99/0038300d04ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/99/108ba746dbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/99/8003b4efb4ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/99/c0d1b349bcac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9a/5047c66c59ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9a/9020bf8105ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9a/90e58c27dbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9a/a0ca38a134ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9a/c0c28d7a6aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9b/4006c59289ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9b/607562f31bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9b/700d3683e7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9b/a0c5a62123ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9c/2087ada01fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9c/701d65425ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9c/d0238e50c3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9c/d051dafe19ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9d/3076b8ce68a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9d/5049179dd5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9d/a0bc950e1eac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9e/e01bd697e1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9f/00cb17ba1dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9f/5007a8de04ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9f/d08d5d2106ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a/30e9d046d4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a/50ae4bb952ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a/a081b90164a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a/c0ee8e47e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a/d022dccc6da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a/d05ac2d168a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a/d0c43373c3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a0/308af7d8f8ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a0/60b6f0541dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a0/9069fa15c3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a0/e0c0b8d904ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a1/003e3e7b4fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a1/50041f4fcfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a1/a07bc2d560ac00171ca19969f19d2325 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a1/b048dcf9f5ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a1/d04b3b71a5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a2/20852d9403ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a2/407e00c504ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a2/5061348b26ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a2/6056f2cb4fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a2/f0d8feae65a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a3/401ed82266ac00171f75fe2361138dfd create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a3/a0965bb1e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a3/e0491a3469a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a4/10baef44f8ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a4/10c20b3ec5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a5/2062891a03ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a6/9039b1d7dfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a7/00e268836da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a7/30568a8fa0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a7/70b19de71dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a7/70c03d9705ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a7/a0902db74fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a7/b0ba96e2d5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a8/4095613d68a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a8/803e3c42d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a8/a04a3bdee7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a8/b0d2e56a05ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a8/c021eb1429ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a8/d054b9f658ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a8/e00509dad7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a9/20cde3669fad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a9/40e9ecc6e6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a9/500e93c5d5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a9/50f9bfc666a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a9/8036f5d929ad001713e0de43c08806fd create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a9/b04660ada0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a9/c081497ec9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a9/c0ecdbb15ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/aa/403bb575e1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/aa/4083116e1dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/aa/70a5f893a3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ab/506f76f61fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ab/70eb261ed8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ab/b09a89816da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ac/30abf1fab4ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ac/805f8d8db5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ac/a0ca04a35ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ad/40667fc262a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ad/4083114ddeac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ad/70fcec3e27ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ae/d0f13c3968a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/af/0088a7b1c9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/af/308465da1bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/af/b087283700ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b/30f2f53008ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b/700303e004ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b/806d1b51b4ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b/9082330aa0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b/c059b6a503ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b0/70d2168260a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b1/0051cea6d5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b1/504219b51dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b1/a0c348acd9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b1/d074365422ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b1/f0e13d3e5ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b2/204ab9a023ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b2/b0190bb66aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b2/d07c71886da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b3/201bd76bb3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b3/40a5f1e8b8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b3/80ea2f8de7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b3/90c2fce664a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b4/30eed20e64a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b4/d047883de1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b4/e0ac193f65a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b5/40399e4003ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b5/90f32a02b3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b5/c0de2650ccac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b6/80a6bd9bb6ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b6/c08c15e6cbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b7/30d491dd37ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b7/708285e958ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b7/8099f407b8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b7/902ed8cecbad00171b48cedc605eece5 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b7/c0821a2b23ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b8/00e80b69c5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b8/504716dd52ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b8/601c95a8d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b8/f048c24722ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b9/10c10c5969a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b9/50671825d4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b9/60d8a6a904ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b9/705e0ff7e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b9/70ab9f9451ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b9/80aea1e1e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b9/90260fc76da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ba/509862f704ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ba/607e6669b5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ba/60fa14012cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ba/b0c8f6cb69a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ba/d0d925c01bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bb/20b3f7a44fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bb/c0320e18e1ad00171536fea4e2c2e8be create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bb/d05f6666dbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bb/f05e24e42aad001713e0de43c08806fd create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bc/e026666d03ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bd/0092f91127ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bd/10315d056ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bd/505d0d6126ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bd/6035a9ef04ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bd/606102f529ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bd/b07a2029d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bd/d0a4982c03ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/be/809095536aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/be/f0170dbcb5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bf/707a9cdbc4ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bf/80cced3d64a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bf/90cc8e0637ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/bf/b0bad2914fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c/00765baba0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c/e0546f7eabac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c0/100a598904ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c0/4069778be0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c0/90fe4f592dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c0/e06728ea05ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c0/f05994565ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c1/1026fc199fad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c1/409b84a8cfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c1/606274b0cdac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c1/90f955d5e1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c1/b02fa6c104ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c1/e00d35ec5fac00171ca19969f19d2325 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c2/0011b739e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c2/50701c5f06ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c2/805d9d5d1eac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c2/b069017f11ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c2/e0564af81dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c2/e0e90fc76da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c3/309944b9a1ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c3/4080f5b2d3ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c3/b06de7a0e1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c3/e05862c8afad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c4/20419ed021ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c4/70c215f856ac00171c63d91e40f02a62 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c4/c01a91c731ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c5/5072b3566aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c6/000d73ae31ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c6/005f226ed4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c6/30d1f210f7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c6/9002149285ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c7/303bbd9222ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c7/306b6cb061ac00171ca19969f19d2325 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c7/50f07caf6aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c8/30cbde246aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c8/b00d77bc6da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c9/20ed8c17d6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ca/f04c3ce267a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cb/20fd1e9c05ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cb/500f92514fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cb/70aced995ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cb/80f3ada6a0ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cb/a053859df4ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cb/b00533b9e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cb/f0426ab665a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cc/20526809d6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cc/908cb5595ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cc/b06dd99a19ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cd/a005d14c1fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cd/c003f191e1ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ce/10663a33dbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ce/80357b80dfad00171536fea4e2c2e8be create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cf/407ed953c3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d0/4051a3aee0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d0/605e9939b5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d0/80a9ccb923ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d0/902a116bd8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d0/f01bbc2423ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d1/206c13f56aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d1/c08fa1f5f6ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d1/e03c398669a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d2/3038caabb2ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d2/40fe2bd9d5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d2/7022b67821ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d2/70c87e2e6aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d3/20d30dea64a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d3/302bfa4709ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d3/403ff763c5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d3/f093a187a2ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d4/40c49ebde0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d4/d0f62a8bf7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d5/0093b68423ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d5/20908afcb3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d5/30a55330acac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d5/40cbe317ccac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d5/50968f281cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d6/b09d47221cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d7/004317ff64a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d7/60d73d281dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d7/70151736b5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d7/f0ad1fce60ac00171ca19969f19d2325 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d8/1085b7f621ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d8/50a569836da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d8/50f176e553ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d8/f00b8baa06ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d8/f05963bc23ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d9/508ad9ba6da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d9/7094428fc4ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d9/b057cfe669a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d9/c009708fd7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d9/d0c9f45526ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/da/40ae3979b9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/da/6081ae6d5ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/da/c0eefdc32aad001713e0de43c08806fd create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/db/d05d7acd7fad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/dc/904dedc619ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/dc/90f0bcbff4ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/dd/00afb2566aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/dd/206f8ef4c4ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/dd/d0aca700e0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/de/305d803423ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/de/400b4c649fad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/de/d0102ea37aad0017139dd5d73065d9ec create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/df/20d826b6d5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/df/90ce9028bbac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/df/e05aea31e5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/df/f0a11525b5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e/609b46bf31ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e/700b1efb5ba800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e0/8092913d24ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e0/a03492f16aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e0/f025dbc769a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e1/80a8e68d04ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e2/20032dc67fad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e2/5020156065a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e2/70b70a8cc3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e2/f0425b8821ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e4/4059f899d9ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e5/203d7a7234ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e5/9061c62a1eac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e5/f0935d6167a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e6/207e4997a3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e6/e08d2b131dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e7/a0e0d9edd5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e8/20b1cad36ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e8/70971d3ce5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e8/b0ddd35cf7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e9/208ee49ef7ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e9/4013f50ee5ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e9/90cd219a05ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e9/a022a50403ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e9/d006eeec21ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e9/d0ff1d71a5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ea/60ecdf1d6fa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ea/9025de20bfac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/eb/2021a16626ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/eb/80166cdc03ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/eb/b0e8f93623ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/eb/c06725bb6aa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/eb/d0940911b8ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ec/00a2d3dd6fa800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ec/803ad67e6da800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ec/80b1fc5504ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ec/b0b90ce869a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ed/d0307bf0c4ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ed/e076043e66a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ee/2060f2c92dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ee/a0e97951e2ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ee/e063a0e405ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f/007161e403ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f/80cfa981e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f0/b00e1d621dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f1/40534e4de0ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f1/4058227a03ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f1/a0ccf39ca2ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f1/f0b1078018ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f2/00fb9210c5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f2/205b62d228ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f2/40de80ad04ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f2/7032eb2669a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f2/70e487be1fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f3/f0a22d5cb5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f4/601a0f24e4ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f4/f0223ffad6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f4/f05a287b21ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f5/8025f0b71cac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f5/d00d8ca969a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f6/305344955ca800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f6/6074ea1c65a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f6/70c6c0fe05ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f6/80457721b5ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f7/40b0cfa5d6ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f7/603bf12c1fac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f7/702d21411aac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f7/70e1c01c67a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f8/60ddb5c326ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f8/70ac59ef1dac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f8/e08fc2e1d7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fa/1096727405ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fb/30fc8d1b66a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fb/e0a01d43f2ab001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fc/10d69239b2ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fc/10f958adb3ad0017181ed9113883eda9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fc/a0fc077523ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fd/a0c92a2bd7ac001716b9ca6d5abb90bc create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fe/502a91841bac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fe/e0de531569a800171a8482560d609ceb create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ff/7095ccf204ac001710ff8a7c6bda0fb8 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.indexes/properties.index create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.markers.snap create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.syncinfo.snap create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/org.eclipse.egit.core/GitProjectData.properties create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/judt/.indexes/e4/9d/9c/history.index create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/judt/.indexes/properties.index create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/judt/.markers.snap create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/judt/.syncinfo.snap create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/judt/org.eclipse.egit.core/GitProjectData.properties create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.root/6.tree create mode 100644 .metadata/.plugins/org.eclipse.core.resources/6.snap create mode 100644 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.egit.core.prefs create mode 100644 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.recommenders.completion.rcp.prefs create mode 100644 .metadata/.plugins/org.eclipse.debug.core/.launches/TestRecFiles.launch create mode 100644 .metadata/.plugins/org.eclipse.debug.core/.launches/TestSendFiles.launch create mode 100644 .metadata/.plugins/org.eclipse.debug.core/.launches/TestServer.launch create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/10.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/12.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/13.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/14.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/15.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/5.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/6.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png create mode 100644 .metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/judt/2017/10/41/refactorings.history create mode 100644 .metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/judt/2017/10/41/refactorings.index create mode 100644 .metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.8.1.20170728-1531.xml create mode 100644 .metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647106718.target create mode 100644 .metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647150848.target create mode 100644 .metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647262388.target create mode 100644 .metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647315540.target create mode 100644 .metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647349336.target create mode 100644 .metadata/.plugins/org.eclipse.pde.core/.local_targets/1507648147331.target create mode 100644 .metadata/.plugins/org.eclipse.pde.core/SavedExternalPluginList.txt create mode 100644 .metadata/.plugins/org.eclipse.ui.workbench.texteditor/dialog_settings.xml create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fdt create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fdx create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fnm create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.frq create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.nrm create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.prx create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.tii create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.tis create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/segments.gen create mode 100644 .recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/segments_9 create mode 100644 Config.xml create mode 100644 Server.bat create mode 100644 Server.jar create mode 100644 judt/bin/.gitignore create mode 100644 judt/bin/Config.xml create mode 100644 judt/src/judp/DataStruct.java create mode 100644 judt/src/judp/PackagetCombin.java create mode 100644 judt/src/judp/PackagetSub.java create mode 100644 judt/src/judp/SocketControls.java create mode 100644 judt/src/judp/SocketReference.java create mode 100644 judt/src/judp/judpGroupSocket.java create mode 100644 judt/src/judp/judpSocketManager.java create mode 100644 judt/src/net/File/FileMonitor.java create mode 100644 judt/src/net/File/FilesWatch.java create mode 100644 judt/src/net/File/PackagetCharSet.java create mode 100644 judt/src/net/File/ReadXml.java create mode 100644 judt/src/net/File/RecviceFiles.java create mode 100644 judt/src/net/File/SendFiles.java create mode 100644 judt/src/net/File/TestRecFiles.java create mode 100644 judt/src/net/File/TestSendFiles.java create mode 100644 recFile.bat create mode 100644 recFile.jar create mode 100644 sendFile.bat create mode 100644 sendFile.jar create mode 100644 sendFiles.jar diff --git a/.metadata/.bak_0.log b/.metadata/.bak_0.log new file mode 100644 index 0000000..32c75ce --- /dev/null +++ b/.metadata/.bak_0.log @@ -0,0 +1,12431 @@ +!SESSION 2017-03-21 20:36:59.126 ----------------------------------------------- +eclipse.buildId=4.6.2.M20161124-1400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-03-21 20:37:57.050 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-03-22 19:42:10.566 ----------------------------------------------- +eclipse.buildId=4.6.2.M20161124-1400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-03-22 19:43:05.670 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-03-22 20:24:11.451 ----------------------------------------------- +eclipse.buildId=4.6.2.M20161124-1400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-03-22 20:25:27.553 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-03-24 02:26:49.142 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-03-24 02:28:34.087 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.e4.ui.workbench 2 0 2017-03-24 02:28:35.379 +!MESSAGE Removing part descriptor with the 'org.eclipse.wb.core.StructureView' id and the 'Structure' description. Points to the invalid 'bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView' class. + +!ENTRY org.eclipse.e4.ui.workbench 2 0 2017-03-24 02:28:35.380 +!MESSAGE Removing part descriptor with the 'org.eclipse.wb.core.PaletteView' id and the 'Palette' description. Points to the invalid 'bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView' class. + +!ENTRY org.eclipse.equinox.p2.transport.ecf 2 0 2017-03-24 02:50:40.841 +!MESSAGE Connection to http://mirror.ufs.ac.za/eclipse/releases/neon/201612211000/features/org.eclipse.wb.core.java.feature_1.9.0.jar failed on Connection timed out: connect. Retry attempt 0 started +!STACK 0 +java.net.ConnectException: Connection timed out: connect + at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) + at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) + at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) + at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) + at java.net.AbstractPlainSocketImpl.connect(Unknown Source) + at java.net.PlainSocketImpl.connect(Unknown Source) + at java.net.SocksSocketImpl.connect(Unknown Source) + at java.net.Socket.connect(Unknown Source) + at org.eclipse.ecf.internal.provider.filetransfer.httpclient4.ECFHttpClientProtocolSocketFactory.connectSocket(ECFHttpClientProtocolSocketFactory.java:86) + at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:177) + at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144) + at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:131) + at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:611) + at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:446) + at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863) + at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) + at org.eclipse.ecf.provider.filetransfer.httpclient4.HttpClientRetrieveFileTransfer.performConnect(HttpClientRetrieveFileTransfer.java:1084) + at org.eclipse.ecf.provider.filetransfer.httpclient4.HttpClientRetrieveFileTransfer.access$0(HttpClientRetrieveFileTransfer.java:1075) + at org.eclipse.ecf.provider.filetransfer.httpclient4.HttpClientRetrieveFileTransfer$1.performFileTransfer(HttpClientRetrieveFileTransfer.java:1071) + at org.eclipse.ecf.filetransfer.FileTransferJob.run(FileTransferJob.java:74) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) +!SESSION 2017-03-24 03:12:38.610 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product -data file:/D:/jinyu/udt-java/ -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-03-24 08:01:57.906 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-03-24 08:05:50.970 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product -product org.eclipse.epp.package.jee.product -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product -product org.eclipse.epp.package.jee.product -data file:/D:/jinyu/udt-java/ -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-03-24 08:06:24.151 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-03-26 01:18:44.784 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-03-26 01:19:15.899 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-03-26 11:08:10.027 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-03-26 11:09:44.150 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-02 01:59:50.264 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-02 02:00:08.715 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.epp.logging.aeri.ide 2 17 2017-04-02 02:00:13.612 +!MESSAGE Server 鈥榦rg.eclipse.epp.logging.aeri.ide.server鈥 failed with exception: Connect to dev.eclipse.org:443 [dev.eclipse.org/198.41.30.200] failed: Read timed out. ; version: 2.0.4.v20170307-1435 +!STACK 0 +org.apache.http.conn.ConnectTimeoutException: Connect to dev.eclipse.org:443 [dev.eclipse.org/198.41.30.200] failed: Read timed out + at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:134) + at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:319) + at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363) + at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219) + at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195) + at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86) + at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) + at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) + at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) + at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57) + at org.apache.http.client.fluent.Executor.execute(Executor.java:206) + at org.eclipse.epp.internal.logging.aeri.ide.server.mars.IO.request(IO.java:206) + at org.eclipse.epp.internal.logging.aeri.ide.server.mars.IO.refreshConfiguration(IO.java:68) + at org.eclipse.epp.internal.logging.aeri.ide.server.mars.ServerConnection.startUp(ServerConnection.java:124) + at com.google.common.util.concurrent.AbstractIdleService$2$1.run(AbstractIdleService.java:54) + at com.google.common.util.concurrent.Callables$3.run(Callables.java:93) + at java.lang.Thread.run(Thread.java:745) +Caused by: java.net.SocketTimeoutException: Read timed out + at java.net.SocketInputStream.socketRead0(Native Method) + at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) + at java.net.SocketInputStream.read(SocketInputStream.java:171) + at java.net.SocketInputStream.read(SocketInputStream.java:141) + at sun.security.ssl.InputRecord.readFully(InputRecord.java:465) + at sun.security.ssl.InputRecord.read(InputRecord.java:503) + at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973) + at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) + at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) + at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) + at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:290) + at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:259) + at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:125) + ... 16 more + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-02 03:51:07.175 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/widget/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl@18ad543b (elementId: org.eclipse.e4.ui.compatibility.editor, tags: [Editor, org.eclipse.jdt.ui.CompilationUnitEditor, removeOnHide], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer@56ed9270, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (contributionURI: bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor, object: org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor@7aadd290, context: PartImpl (org.eclipse.e4.ui.compatibility.editor) Context, variables: [], label: UDTServerSocket.java, iconURI: platform:/plugin/org.eclipse.jdt.ui/icons/full/obj16/jcu_obj.png, tooltip: null, dirty: false, closeable: true, description: null), Widget=null, org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl@18ad543b (elementId: org.eclipse.e4.ui.compatibility.editor, tags: [Editor, org.eclipse.jdt.ui.CompilationUnitEditor, removeOnHide], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer@56ed9270, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (contributionURI: bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor, object: org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor@7aadd290, context: PartImpl (org.eclipse.e4.ui.compatibility.editor) Context, variables: [], label: UDTServerSocket.java, iconURI: platform:/plugin/org.eclipse.jdt.ui/icons/full/obj16/jcu_obj.png, tooltip: null, dirty: false, closeable: true, description: null), AttName=widget, EventType=SET, OldValue=ContributedPartRenderer$2 {}, Widget=null}, AttName=widget, EventType=SET, OldValue=ContributedPartRenderer$2 {}} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@4ab909f4 +!STACK 0 +java.lang.NullPointerException + at org.eclipse.ui.internal.NavigationHistory.getDisplay(NavigationHistory.java:176) + at org.eclipse.ui.internal.NavigationHistory.markEditor(NavigationHistory.java:193) + at org.eclipse.ui.internal.WorkbenchPage.updateActiveEditorSources(WorkbenchPage.java:411) + at org.eclipse.ui.internal.WorkbenchPage.firePartClosed(WorkbenchPage.java:5164) + at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart$1.handleEvent(CompatibilityPart.java:102) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Canvas.releaseChildren(Canvas.java:171) + at org.eclipse.swt.widgets.Decorations.releaseChildren(Decorations.java:807) + at org.eclipse.swt.widgets.Shell.releaseChildren(Shell.java:1368) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3875) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +!SESSION 2017-04-02 14:35:06.822 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-02 14:35:48.921 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.e4.ui.workbench 4 0 2017-04-02 18:56:14.941 +!MESSAGE Error disposing widget for : org.eclipse.e4.ui.model.application.ui.menu.impl.MenuImpl null +!STACK 0 +org.eclipse.swt.SWTException: Graphic is disposed + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.Font.getFontData(Font.java:192) + at org.eclipse.swt.custom.CTabFolderRenderer.drawChevron(CTabFolderRenderer.java:909) + at org.eclipse.swt.custom.CTabFolderRenderer.draw(CTabFolderRenderer.java:605) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.draw(CTabRendering.java:252) + at org.eclipse.swt.custom.CTabFolder.createButtonImage(CTabFolder.java:721) + at org.eclipse.swt.custom.CTabFolder.setButtonBounds(CTabFolder.java:2541) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3766) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3697) + at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2090) + at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:340) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.sendResize(Control.java:3042) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1058) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1062) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1030) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:996) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1210) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1801) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1849) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1187) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:176) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:918) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:846) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$3.run(PartRenderingEngine.java:841) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:825) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:322) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3875) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) + at org.eclipse.swt.internal.win32.OS.CallWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.CallWindowProc(OS.java:2446) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:483) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2197) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) + at org.eclipse.swt.internal.win32.OS.CallWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.CallWindowProc(OS.java:2446) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:483) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2197) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +!SESSION 2017-04-02 23:54:19.701 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-02 23:59:27.171 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:37.584 +!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Worker-5,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Worker-5,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.getContents(ReadManager.java:145) + at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11374) + at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11346) + at org.eclipse.jdt.internal.compiler.parser.Parser.dietParse(Parser.java:9760) + at org.eclipse.jdt.internal.compiler.Compiler.internalBeginToCompile(Compiler.java:815) + at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:385) + at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:431) + at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:417) + at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:368) + at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:179) + at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:305) + at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:61) + at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:256) + at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:175) + at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:735) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206) + at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246) + at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:301) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:304) + at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:360) + at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:383) + at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144) + at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 57 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.getContents(ReadManager.java:145) + at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11374) + at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11346) + at org.eclipse.jdt.internal.compiler.parser.Parser.dietParse(Parser.java:9760) + at org.eclipse.jdt.internal.compiler.Compiler.internalBeginToCompile(Compiler.java:815) + at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:385) + at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:431) + at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:417) + at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:368) + at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:179) + at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:305) + at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:61) + at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:256) + at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:175) + at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:735) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206) + at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246) + at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:301) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:304) + at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:360) + at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:383) + at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144) + at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) + +!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.158 +!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 33 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) + +!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.159 +!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 33 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) + +!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.160 +!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 33 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) + +!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.161 +!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 33 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) + +!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.162 +!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 33 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) + +!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.163 +!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 33 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) + +!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.163 +!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 33 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) + +!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.164 +!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 33 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) + at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) + at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) + at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) + at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) + at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) + at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) + at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) + at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) + at org.eclipse.core.internal.resources.File.getCharset(File.java:198) + at org.eclipse.core.internal.resources.File.getCharset(File.java:186) + at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) + at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) + at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) + at java.lang.Thread.run(Thread.java:745) + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-03 00:13:28.827 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@5e4b9f22 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@5e4b9f22 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1cd9c2de +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-03 00:13:47.986 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@1e695be6 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@1e695be6 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1cd9c2de +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more + +!ENTRY org.eclipse.jface.text 2 0 2017-04-03 00:14:05.541 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-03 00:14:05.542 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-03 00:14:06.351 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-03 00:14:06.352 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-03 00:14:28.440 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@71bcc154 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@71bcc154 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1cd9c2de +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-03 00:14:41.129 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@4260f222 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@4260f222 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1cd9c2de +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more +!SESSION 2017-04-03 13:15:47.065 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.osgi 2 0 2017-04-03 13:20:48.672 +!MESSAGE While loading class "org.eclipse.egit.ui.internal.ConfigurationChecker$1$1", thread "Thread[Worker-0,5,main]" timed out waiting (5010ms) for thread "Thread[main,6,main]" to finish starting bundle "org.eclipse.egit.ui_4.6.1.201703071140-r [1025]". To avoid deadlock, thread "Thread[Worker-0,5,main]" is proceeding but "org.eclipse.egit.ui.internal.ConfigurationChecker$1$1" may not be fully initialized. +!STACK 0 +org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="4.6.1.201703071140-r"; osgi.identity="org.eclipse.egit.ui"; singleton:="true" [id=1025] STARTED [STARTED] + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:423) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.egit.ui.internal.ConfigurationChecker$1.run(ConfigurationChecker.java:45) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) +Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + ... 13 more +Root exception: +java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. + at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) + at org.eclipse.osgi.container.Module.start(Module.java:401) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:423) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) + at java.lang.ClassLoader.loadClass(ClassLoader.java:357) + at org.eclipse.egit.ui.internal.ConfigurationChecker$1.run(ConfigurationChecker.java:45) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 13:23:48.986 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-03 14:07:53.429 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 14:11:19.044 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-03 16:52:58.264 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 16:53:09.914 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-03 18:13:48.775 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 18:14:00.127 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-03 21:03:59.376 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 21:04:18.275 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-03 21:49:22.479 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 21:49:42.879 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-03 23:52:06.346 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 23:52:20.464 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-04 01:10:35.356 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-04 01:10:50.441 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-04-04 01:25:16.037 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-04 01:25:16.055 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.e4.ui.workbench 4 0 2017-04-04 04:25:44.802 +!MESSAGE Error disposing widget for : org.eclipse.e4.ui.model.application.ui.menu.impl.MenuImpl null +!STACK 0 +java.lang.IllegalArgumentException: Argument not valid + at org.eclipse.swt.SWT.error(SWT.java:4514) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.GC.setFont(GC.java:4617) + at org.eclipse.swt.custom.CTabFolderRenderer.computeSize(CTabFolderRenderer.java:340) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.computeSize(CTabRendering.java:200) + at org.eclipse.swt.custom.CTabFolder.setItemSize(CTabFolder.java:2819) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3764) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3697) + at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2090) + at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:340) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.sendResize(Control.java:3042) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1058) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1062) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1030) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:996) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1210) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1801) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1849) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1187) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:176) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:918) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:846) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$3.run(PartRenderingEngine.java:841) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:825) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:322) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3875) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.VtblCall(Native Method) + at org.eclipse.swt.widgets.TaskItem.setOverlayImage(TaskItem.java:296) + at org.eclipse.ui.internal.progress.TaskBarProgressManager.updateImage(TaskBarProgressManager.java:159) + at org.eclipse.ui.internal.progress.TaskBarProgressManager.access$4(TaskBarProgressManager.java:153) + at org.eclipse.ui.internal.progress.TaskBarProgressManager$2.runInUIThread(TaskBarProgressManager.java:117) + at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:97) + at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) + at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) + at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4211) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3827) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-04 04:25:44.955 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/widget/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl@1eb906f3 (elementId: org.eclipse.e4.ui.compatibility.editor, tags: [Editor, org.eclipse.jdt.ui.CompilationUnitEditor, removeOnHide], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer@2be89ba5, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (contributionURI: bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor, object: org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor@33ef701e, context: PartImpl (org.eclipse.e4.ui.compatibility.editor) Context, variables: [], label: ClientSession.java, iconURI: platform:/plugin/org.eclipse.jdt.ui/icons/full/obj16/jcu_obj.png, tooltip: null, dirty: false, closeable: true, description: null), Widget=null, org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl@1eb906f3 (elementId: org.eclipse.e4.ui.compatibility.editor, tags: [Editor, org.eclipse.jdt.ui.CompilationUnitEditor, removeOnHide], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer@2be89ba5, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (contributionURI: bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor, object: org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor@33ef701e, context: PartImpl (org.eclipse.e4.ui.compatibility.editor) Context, variables: [], label: ClientSession.java, iconURI: platform:/plugin/org.eclipse.jdt.ui/icons/full/obj16/jcu_obj.png, tooltip: null, dirty: false, closeable: true, description: null), AttName=widget, EventType=SET, OldValue=ContributedPartRenderer$2 {}, Widget=null}, AttName=widget, EventType=SET, OldValue=ContributedPartRenderer$2 {}} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1ea3309a +!STACK 0 +java.lang.NullPointerException + at org.eclipse.ui.internal.NavigationHistory.getDisplay(NavigationHistory.java:176) + at org.eclipse.ui.internal.NavigationHistory.markEditor(NavigationHistory.java:193) + at org.eclipse.ui.internal.WorkbenchPage.updateActiveEditorSources(WorkbenchPage.java:411) + at org.eclipse.ui.internal.WorkbenchPage.firePartClosed(WorkbenchPage.java:5164) + at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart$1.handleEvent(CompatibilityPart.java:102) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) + at org.eclipse.swt.widgets.Canvas.releaseChildren(Canvas.java:171) + at org.eclipse.swt.widgets.Decorations.releaseChildren(Decorations.java:807) + at org.eclipse.swt.widgets.Shell.releaseChildren(Shell.java:1368) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3875) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.VtblCall(Native Method) + at org.eclipse.swt.widgets.TaskItem.setOverlayImage(TaskItem.java:296) + at org.eclipse.ui.internal.progress.TaskBarProgressManager.updateImage(TaskBarProgressManager.java:159) + at org.eclipse.ui.internal.progress.TaskBarProgressManager.access$4(TaskBarProgressManager.java:153) + at org.eclipse.ui.internal.progress.TaskBarProgressManager$2.runInUIThread(TaskBarProgressManager.java:117) + at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:97) + at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) + at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) + at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4211) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3827) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +!SESSION 2017-04-04 17:28:24.334 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.core.resources 2 10035 2017-04-04 17:28:32.785 +!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-04 17:28:41.471 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-04-04 17:32:45.473 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-04 17:32:45.475 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-04 17:35:12.546 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@4e4f979f (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@440e2406, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@4e4f979f (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@440e2406, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@165abf1 +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more + +!ENTRY org.eclipse.ui 4 0 2017-04-04 17:35:14.020 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-04 17:35:49.040 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@507f7caa (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@440e2406, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@507f7caa (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@440e2406, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@165abf1 +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more + +!ENTRY org.eclipse.ui 4 0 2017-04-04 17:35:50.602 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more +!SESSION 2017-04-04 18:07:28.299 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-04 18:07:37.718 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-04 20:23:39.571 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-04 20:24:42.106 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-04-05 01:23:19.257 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-05 01:23:19.316 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-05 01:43:16.807 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-05 01:43:16.807 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.e4.ui.workbench 4 0 2017-04-05 02:20:07.842 +!MESSAGE Error disposing widget for : org.eclipse.e4.ui.model.application.ui.menu.impl.MenuImpl null +!STACK 0 +java.lang.IllegalArgumentException: Argument not valid + at org.eclipse.swt.SWT.error(SWT.java:4514) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.GC.setFont(GC.java:4617) + at org.eclipse.swt.custom.CTabFolderRenderer.computeSize(CTabFolderRenderer.java:340) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.computeSize(CTabRendering.java:200) + at org.eclipse.swt.custom.CTabFolder.setItemSize(CTabFolder.java:2819) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3764) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3697) + at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2090) + at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:340) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.sendResize(Control.java:3042) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1058) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1062) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1030) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:996) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1210) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1801) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1849) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1187) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:176) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:918) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:846) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$3.run(PartRenderingEngine.java:841) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:825) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:322) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3875) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.VtblCall(Native Method) + at org.eclipse.swt.widgets.TaskItem.setOverlayImage(TaskItem.java:296) + at org.eclipse.ui.internal.progress.TaskBarProgressManager.updateImage(TaskBarProgressManager.java:159) + at org.eclipse.ui.internal.progress.TaskBarProgressManager.access$4(TaskBarProgressManager.java:153) + at org.eclipse.ui.internal.progress.TaskBarProgressManager$2.runInUIThread(TaskBarProgressManager.java:117) + at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:97) + at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) + at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) + at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4211) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3827) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) + at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +!SESSION 2017-04-05 22:26:22.175 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.core.resources 2 10035 2017-04-05 22:26:29.318 +!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-05 22:26:36.687 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-06 00:47:18.247 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 00:47:50.832 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-06 02:03:23.389 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:03:44.687 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 02:04:07.770 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@78fdc1bb (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@75707f05, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@78fdc1bb (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@75707f05, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@6fffad6d +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more + +!ENTRY org.eclipse.ui 4 0 2017-04-06 02:04:10.005 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more +!SESSION 2017-04-06 02:08:17.558 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:08:38.242 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 02:08:41.170 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@3d45ea17 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@6971f5f4, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@3d45ea17 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@6971f5f4, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@562b791b +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more + +!ENTRY org.eclipse.ui 4 0 2017-04-06 02:08:44.687 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-04-06 02:08:44.787 +!MESSAGE Unhandled event loop exception +!STACK 0 +java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 + at java.util.ArrayList.rangeCheck(ArrayList.java:653) + at java.util.ArrayList.get(ArrayList.java:429) + at org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.ConfigureBuildPathAction.run(ConfigureBuildPathAction.java:63) + at org.eclipse.jface.action.Action.runWithEvent(Action.java:473) + at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:565) + at org.eclipse.jface.action.ActionContributionItem.lambda$4(ActionContributionItem.java:397) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4236) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3824) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 02:08:49.521 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@6896ef29 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@6971f5f4, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@6896ef29 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@6971f5f4, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@562b791b +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more +!SESSION 2017-04-06 02:21:00.143 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:21:23.640 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-04-06 02:28:12.434 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-06 02:28:12.437 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 02:31:03.685 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@3afbd1fd (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@10007fdc, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@3afbd1fd (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@10007fdc, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@5e31ad69 +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more + +!ENTRY org.eclipse.ui 4 0 2017-04-06 02:31:05.552 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more +!SESSION 2017-04-06 02:49:58.774 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:50:15.871 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-06 02:50:30.453 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:50:42.826 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-04-06 03:01:55.359 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-04-06 03:01:55.361 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 03:04:22.938 +!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@116c5bfa (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@116c5bfa (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@456839ee +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) + at org.eclipse.equinox.launcher.Main.run(Main.java:1519) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(FileInputStream.java:195) + at java.io.FileInputStream.(FileInputStream.java:138) + at java.io.FileInputStream.(FileInputStream.java:93) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 75 more +!SESSION 2017-04-17 03:24:29.378 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-17 03:24:51.826 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-04-17 03:25:49.972 ----------------------------------------------- +eclipse.buildId=4.6.3.M20170301-0400 +java.version=1.8.0_121 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-04-17 03:25:58.567 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-08-28 00:39:00.693 ----------------------------------------------- +eclipse.buildId=4.7.0.I20170612-0950 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:39:15.622 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-08-28 00:40:50.014 ----------------------------------------------- +eclipse.buildId=4.7.0.I20170612-0950 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:41:00.718 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-08-28 00:42:12.549 ----------------------------------------------- +eclipse.buildId=4.7.0.I20170612-0950 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:42:24.071 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-08-28 00:43:41.933 ----------------------------------------------- +eclipse.buildId=4.7.0.I20170612-0950 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:43:52.374 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-08-28 00:49:21.174 ----------------------------------------------- +eclipse.buildId=4.7.0.I20170612-0950 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:49:54.423 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-10-04 00:06:00.830 ----------------------------------------------- +eclipse.buildId=4.7.0.I20170612-0950 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-04 00:06:55.748 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-10-04 00:47:37.369 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-04 00:47:37.370 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-04 00:48:52.844 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-04 00:48:52.844 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.ui 4 0 2017-10-04 03:24:41.753 +!MESSAGE Unhandled event loop exception +!STACK 0 +java.lang.IllegalArgumentException: Argument not valid + at org.eclipse.swt.SWT.error(SWT.java:4514) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.GC.setFont(GC.java:4617) + at org.eclipse.swt.custom.CTabFolderRenderer.computeSize(CTabFolderRenderer.java:340) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.computeSize(CTabRendering.java:198) + at org.eclipse.swt.custom.CTabFolder.setItemSize(CTabFolder.java:2839) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3784) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3717) + at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2110) + at org.eclipse.swt.custom.CTabFolder.lambda$0(CTabFolder.java:335) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.sendResize(Control.java:3087) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1035) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1007) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:973) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1187) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1778) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1850) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1188) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:172) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:940) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:868) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:863) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:847) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:322) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1155) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1044) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.ui 4 0 2017-10-04 03:24:43.003 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: Graphic is disposed + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.Font.getFontData(Font.java:192) + at org.eclipse.swt.custom.CTabFolderRenderer.drawChevron(CTabFolderRenderer.java:909) + at org.eclipse.swt.custom.CTabFolderRenderer.draw(CTabFolderRenderer.java:605) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.draw(CTabRendering.java:251) + at org.eclipse.swt.custom.CTabFolder.createButtonImage(CTabFolder.java:747) + at org.eclipse.swt.custom.CTabFolder.setButtonBounds(CTabFolder.java:2561) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3786) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3717) + at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2110) + at org.eclipse.swt.custom.CTabFolder.lambda$0(CTabFolder.java:335) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.sendResize(Control.java:3087) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1035) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1007) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:973) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1187) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1778) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1850) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1188) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:172) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:940) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:868) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:863) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:847) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:322) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1155) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1044) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.e4.ui.css.swt.theme 4 0 2017-10-04 03:24:43.003 +!MESSAGE Graphic is disposed +!STACK 0 +org.eclipse.swt.SWTException: Graphic is disposed + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.Font.getFontData(Font.java:192) + at org.eclipse.e4.ui.css.swt.helpers.CSSSWTFontHelper.getFirstFontData(CSSSWTFontHelper.java:459) + at org.eclipse.e4.ui.css.swt.properties.converters.CSSValueSWTFontDataConverterImpl.convert(CSSValueSWTFontDataConverterImpl.java:59) + at org.eclipse.e4.ui.css.swt.properties.converters.CSSValueSWTFontConverterImpl.convert(CSSValueSWTFontConverterImpl.java:34) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.convert(AbstractCSSEngine.java:1124) + at org.eclipse.e4.ui.css.swt.properties.css2.CSSPropertyFontSWTHandler.onAllCSSPropertiesApplyed(CSSPropertyFontSWTHandler.java:251) + at org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler2.onAllCSSPropertiesApplyed(ICSSPropertyHandler2.java:44) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.applyStyleDeclaration(AbstractCSSEngine.java:581) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.applyStyles(AbstractCSSEngine.java:426) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.applyStyles(AbstractCSSEngine.java:367) + at org.eclipse.e4.ui.css.swt.engine.CSSSWTApplyStylesListener$1.handleEvent(CSSSWTApplyStylesListener.java:32) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.runSkin(Display.java:4321) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1361) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1007) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:973) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1187) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1778) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1850) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1188) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:172) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:940) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:868) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:863) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:847) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:322) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1155) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1044) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.ui 4 0 2017-10-04 03:24:43.128 +!MESSAGE Unhandled event loop exception +!STACK 0 +java.lang.NullPointerException + at org.eclipse.ui.internal.NavigationHistory.getDisplay(NavigationHistory.java:176) + at org.eclipse.ui.internal.NavigationHistory.markEditor(NavigationHistory.java:193) + at org.eclipse.ui.internal.WorkbenchPage.updateActiveEditorSources(WorkbenchPage.java:418) + at org.eclipse.ui.internal.WorkbenchPage.firePartClosed(WorkbenchPage.java:5177) + at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.lambda$0(CompatibilityPart.java:104) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Canvas.releaseChildren(Canvas.java:171) + at org.eclipse.swt.widgets.Decorations.releaseChildren(Decorations.java:808) + at org.eclipse.swt.widgets.Shell.releaseChildren(Shell.java:1368) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1155) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1044) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +!SESSION 2017-10-08 14:03:53.565 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.core.resources 2 10035 2017-10-08 14:05:13.130 +!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. + +!ENTRY org.eclipse.e4.ui.workbench 2 0 2017-10-08 14:12:51.564 +!MESSAGE Removing part descriptor with the 'org.eclipse.wb.core.StructureView' id and the 'Structure' description. Points to the invalid 'bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView' class. + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-08 14:12:56.587 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.e4.ui.workbench 2 0 2017-10-08 14:13:00.383 +!MESSAGE Removing part descriptor with the 'org.eclipse.wb.core.PaletteView' id and the 'Palette' description. Points to the invalid 'bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView' class. + +!ENTRY org.eclipse.ui 4 0 2017-10-08 14:37:03.662 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 14:37:07.209 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 14:41:26.801 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 14:41:27.311 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 14:41:28.196 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.jface.text 2 0 2017-10-08 14:45:16.502 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-08 14:45:16.503 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.recommenders.models.rcp 1 11 2017-10-08 14:45:19.760 +!MESSAGE The model index service was accessed either before it started or after it finished running. +!STACK 0 +org.eclipse.recommenders.utils.Logs$LogTraceException + at org.eclipse.recommenders.utils.Logs$LogTraceException.newTrace(Logs.java:381) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:134) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:126) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelIndex.suggest(EclipseModelIndex.java:211) + at org.eclipse.recommenders.models.SimpleModelProvider.acquireModel(SimpleModelProvider.java:70) + at org.eclipse.recommenders.models.PoolingModelProvider.access$0(PoolingModelProvider.java:1) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:96) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:1) + at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1220) + at org.eclipse.recommenders.models.PoolingModelProvider.acquireModel(PoolingModelProvider.java:67) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:65) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:1) + at org.eclipse.recommenders.internal.models.rcp.PrefetchModelArchiveJob.run(PrefetchModelArchiveJob.java:43) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 14:49:51.720 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.connector.basic.ArtifactTransportListener.transferFailed(ArtifactTransportListener.java:52) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector$TaskRunner.run(BasicRepositoryConnector.java:364) + at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:76) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector$DirectExecutor.execute(BasicRepositoryConnector.java:590) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector.get(BasicRepositoryConnector.java:258) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:529) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more +Caused by: org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:178) + at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:137) + at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:150) + at org.eclipse.aether.spi.connector.transport.AbstractTransporter.copy(AbstractTransporter.java:209) + at org.eclipse.aether.spi.connector.transport.AbstractTransporter.utilGet(AbstractTransporter.java:105) + at org.eclipse.aether.transport.http.HttpTransporter.access$100(HttpTransporter.java:81) + at org.eclipse.aether.transport.http.HttpTransporter$EntityGetter.handle(HttpTransporter.java:525) + at org.eclipse.aether.transport.http.HttpTransporter.execute(HttpTransporter.java:303) + at org.eclipse.aether.transport.http.HttpTransporter.implGet(HttpTransporter.java:252) + at org.eclipse.aether.spi.connector.transport.AbstractTransporter.get(AbstractTransporter.java:68) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector$GetTaskRunner.runTask(BasicRepositoryConnector.java:456) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector$TaskRunner.run(BasicRepositoryConnector.java:359) + ... 13 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 14:49:51.722 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 14:49:51.726 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 14:49:51.727 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.jface.text 2 0 2017-10-08 15:03:17.651 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-08 15:03:17.651 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:12:32.126 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:12:32.127 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.ui 4 0 2017-10-08 15:15:29.844 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 15:15:30.547 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:16:48.364 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:16:48.365 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:16:53.161 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:16:53.162 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.ui 4 0 2017-10-08 15:22:38.178 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:31:44.142 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:31:44.143 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:34:07.823 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:34:07.824 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:34:19.413 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:34:19.414 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:34:36.525 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5991813; received: 525308 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:34:36.526 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:54:17.456 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.connector.basic.ArtifactTransportListener.transferFailed(ArtifactTransportListener.java:52) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector$TaskRunner.run(BasicRepositoryConnector.java:364) + at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:76) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector$DirectExecutor.execute(BasicRepositoryConnector.java:590) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector.get(BasicRepositoryConnector.java:258) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:529) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more +Caused by: org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:178) + at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:137) + at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:150) + at org.eclipse.aether.spi.connector.transport.AbstractTransporter.copy(AbstractTransporter.java:209) + at org.eclipse.aether.spi.connector.transport.AbstractTransporter.utilGet(AbstractTransporter.java:105) + at org.eclipse.aether.transport.http.HttpTransporter.access$100(HttpTransporter.java:81) + at org.eclipse.aether.transport.http.HttpTransporter$EntityGetter.handle(HttpTransporter.java:525) + at org.eclipse.aether.transport.http.HttpTransporter.execute(HttpTransporter.java:303) + at org.eclipse.aether.transport.http.HttpTransporter.implGet(HttpTransporter.java:252) + at org.eclipse.aether.spi.connector.transport.AbstractTransporter.get(AbstractTransporter.java:68) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector$GetTaskRunner.runTask(BasicRepositoryConnector.java:456) + at org.eclipse.aether.connector.basic.BasicRepositoryConnector$TaskRunner.run(BasicRepositoryConnector.java:359) + ... 13 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:54:17.561 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:54:17.564 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:54:17.565 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 15:58:02.259 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 15:58:02.260 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.ui 4 0 2017-10-08 16:10:27.170 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 16:10:32.943 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 16:10:33.098 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 16:33:08.239 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 16:33:08.257 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 16:33:23.301 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 16:33:23.302 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 16:35:13.988 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 16:35:13.989 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 16:35:42.138 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 16:35:42.139 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 16:41:18.860 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 16:41:18.862 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 16:41:39.265 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 16:41:39.266 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 16:41:46.828 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 16:41:46.829 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 16:48:40.770 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 16:48:40.771 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2017-10-08 16:51:33.503 +!MESSAGE Failed to download jre:jre:call:zip:1.0.0 +!STACK 0 +org.eclipse.aether.resolution.ArtifactResolutionException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:255) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:232) + at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:303) + at org.eclipse.recommenders.models.ModelRepository.resolveInternal(ModelRepository.java:193) + at org.eclipse.recommenders.models.ModelRepository.resolve(ModelRepository.java:172) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelRepository.resolve(EclipseModelRepository.java:168) + at org.eclipse.recommenders.internal.models.rcp.DownloadModelArchiveJob.run(DownloadModelArchiveJob.java:76) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Failure to transfer jre:jre:zip:call:1.0.0-20160630.185625-2 from http://download.eclipse.org/recommenders/models/oxygen/ was cached in the local repository, resolution will not be reattempted until the update interval of models has elapsed or updates are forced. Original error: Could not transfer artifact jre:jre:zip:call:1.0.0-20160630.185625-2 from/to models (http://download.eclipse.org/recommenders/models/oxygen/): Premature end of Content-Length delimited message body (expected: 5466505; received: 632000 + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.newException(DefaultUpdateCheckManager.java:247) + at org.eclipse.aether.internal.impl.DefaultUpdateCheckManager.checkArtifact(DefaultUpdateCheckManager.java:215) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.gatherDownloads(DefaultArtifactResolver.java:594) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:512) + at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:430) + ... 8 more + +!ENTRY org.eclipse.recommenders.models.rcp 1 0 2017-10-08 16:51:33.505 +!MESSAGE jre:jre:call:zip:1.0.0 could not be resolved from the model repositories. Are you offline? + +!ENTRY org.eclipse.ui 4 0 2017-10-08 16:57:58.651 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 16:57:59.375 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 16:58:09.147 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 17:16:08.153 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 17:16:08.671 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 17:17:08.680 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 18:12:52.640 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 18:44:53.373 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 18:44:54.056 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 18:48:59.957 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 18:50:04.342 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 19:04:16.687 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 19:19:15.094 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 19:20:50.878 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 20:54:04.273 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 20:55:50.054 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 20:55:50.689 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 20:58:47.667 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 20:58:48.409 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 21:11:07.671 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 21:11:08.427 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 21:11:33.538 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 21:17:56.675 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 21:17:57.143 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 21:42:51.725 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 22:39:20.831 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 22:39:28.883 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 22:39:29.390 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.jdt.debug.ui 4 150 2017-10-08 22:41:05.667 +!MESSAGE Internal Error +!STACK 1 +org.eclipse.debug.core.DebugException: com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine occurred while retrieving value. + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.throwDebugException(JDIDebugElement.java:263) + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.requestFailed(JDIDebugElement.java:202) + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.targetRequestFailed(JDIDebugElement.java:182) + at org.eclipse.jdt.internal.debug.core.model.JDIVariable.getCurrentValue(JDIVariable.java:74) + at org.eclipse.jdt.internal.debug.core.model.JDIVariable.getValue(JDIVariable.java:96) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:696) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:710) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener$1.run(JavaDetailFormattersManager.java:664) + at org.eclipse.jdt.internal.debug.core.model.JDIThread.runEvaluation(JDIThread.java:828) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.valueToString(JavaDetailFormattersManager.java:673) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.resolveFormatter(JavaDetailFormattersManager.java:167) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.access$1(JavaDetailFormattersManager.java:140) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$1.run(JavaDetailFormattersManager.java:135) + at org.eclipse.jdt.internal.debug.core.model.JDIThread$ThreadJob.run(JDIThread.java:3529) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine + at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) + at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:204) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:192) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:227) + at org.eclipse.jdi.internal.ArrayReferenceImpl.getValues(ArrayReferenceImpl.java:124) + at org.eclipse.jdi.internal.ArrayReferenceImpl.getValue(ArrayReferenceImpl.java:73) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayEntryVariable.retrieveValue(JDIArrayEntryVariable.java:87) + at org.eclipse.jdt.internal.debug.core.model.JDIVariable.getCurrentValue(JDIVariable.java:72) + ... 11 more +!SUBENTRY 1 org.eclipse.jdt.debug 4 5010 2017-10-08 22:41:05.733 +!MESSAGE com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine occurred while retrieving value. +!STACK 0 +com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine + at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) + at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:204) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:192) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:227) + at org.eclipse.jdi.internal.ArrayReferenceImpl.getValues(ArrayReferenceImpl.java:124) + at org.eclipse.jdi.internal.ArrayReferenceImpl.getValue(ArrayReferenceImpl.java:73) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayEntryVariable.retrieveValue(JDIArrayEntryVariable.java:87) + at org.eclipse.jdt.internal.debug.core.model.JDIVariable.getCurrentValue(JDIVariable.java:72) + at org.eclipse.jdt.internal.debug.core.model.JDIVariable.getValue(JDIVariable.java:96) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:696) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:710) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener$1.run(JavaDetailFormattersManager.java:664) + at org.eclipse.jdt.internal.debug.core.model.JDIThread.runEvaluation(JDIThread.java:828) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.valueToString(JavaDetailFormattersManager.java:673) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.resolveFormatter(JavaDetailFormattersManager.java:167) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.access$1(JavaDetailFormattersManager.java:140) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$1.run(JavaDetailFormattersManager.java:135) + at org.eclipse.jdt.internal.debug.core.model.JDIThread$ThreadJob.run(JDIThread.java:3529) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.jdt.debug.ui 4 150 2017-10-08 22:41:05.734 +!MESSAGE Internal Error +!STACK 1 +org.eclipse.debug.core.DebugException: com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine occurred while retrieving array length. + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.throwDebugException(JDIDebugElement.java:263) + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.requestFailed(JDIDebugElement.java:202) + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.targetRequestFailed(JDIDebugElement.java:182) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayValue.getLength(JDIArrayValue.java:81) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:690) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:710) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener$1.run(JavaDetailFormattersManager.java:664) + at org.eclipse.jdt.internal.debug.core.model.JDIThread.runEvaluation(JDIThread.java:828) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.valueToString(JavaDetailFormattersManager.java:673) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.resolveFormatter(JavaDetailFormattersManager.java:167) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.access$1(JavaDetailFormattersManager.java:140) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$1.run(JavaDetailFormattersManager.java:135) + at org.eclipse.jdt.internal.debug.core.model.JDIThread$ThreadJob.run(JDIThread.java:3529) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine + at org.eclipse.jdi.internal.connect.PacketSendManager.sendPacket(PacketSendManager.java:90) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:187) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:227) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:243) + at org.eclipse.jdi.internal.ArrayReferenceImpl.length(ArrayReferenceImpl.java:230) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayValue.getLength(JDIArrayValue.java:79) + ... 10 more +!SUBENTRY 1 org.eclipse.jdt.debug 4 5010 2017-10-08 22:41:05.735 +!MESSAGE com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine occurred while retrieving array length. +!STACK 0 +com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine + at org.eclipse.jdi.internal.connect.PacketSendManager.sendPacket(PacketSendManager.java:90) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:187) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:227) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:243) + at org.eclipse.jdi.internal.ArrayReferenceImpl.length(ArrayReferenceImpl.java:230) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayValue.getLength(JDIArrayValue.java:79) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:690) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:710) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener$1.run(JavaDetailFormattersManager.java:664) + at org.eclipse.jdt.internal.debug.core.model.JDIThread.runEvaluation(JDIThread.java:828) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.valueToString(JavaDetailFormattersManager.java:673) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.resolveFormatter(JavaDetailFormattersManager.java:167) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.access$1(JavaDetailFormattersManager.java:140) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$1.run(JavaDetailFormattersManager.java:135) + at org.eclipse.jdt.internal.debug.core.model.JDIThread$ThreadJob.run(JDIThread.java:3529) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.jdt.debug.ui 4 150 2017-10-08 22:41:05.735 +!MESSAGE Internal Error +!STACK 1 +org.eclipse.debug.core.DebugException: com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine occurred while retrieving array length. + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.throwDebugException(JDIDebugElement.java:263) + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.requestFailed(JDIDebugElement.java:202) + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.targetRequestFailed(JDIDebugElement.java:182) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayValue.getLength(JDIArrayValue.java:81) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:690) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:710) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener$1.run(JavaDetailFormattersManager.java:664) + at org.eclipse.jdt.internal.debug.core.model.JDIThread.runEvaluation(JDIThread.java:828) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.valueToString(JavaDetailFormattersManager.java:673) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.resolveFormatter(JavaDetailFormattersManager.java:167) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.access$1(JavaDetailFormattersManager.java:140) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$1.run(JavaDetailFormattersManager.java:135) + at org.eclipse.jdt.internal.debug.core.model.JDIThread$ThreadJob.run(JDIThread.java:3529) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine + at org.eclipse.jdi.internal.connect.PacketSendManager.sendPacket(PacketSendManager.java:90) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:187) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:227) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:243) + at org.eclipse.jdi.internal.ArrayReferenceImpl.length(ArrayReferenceImpl.java:230) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayValue.getLength(JDIArrayValue.java:79) + ... 10 more +!SUBENTRY 1 org.eclipse.jdt.debug 4 5010 2017-10-08 22:41:05.736 +!MESSAGE com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine occurred while retrieving array length. +!STACK 0 +com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine + at org.eclipse.jdi.internal.connect.PacketSendManager.sendPacket(PacketSendManager.java:90) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:187) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:227) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:243) + at org.eclipse.jdi.internal.ArrayReferenceImpl.length(ArrayReferenceImpl.java:230) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayValue.getLength(JDIArrayValue.java:79) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:690) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:710) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener$1.run(JavaDetailFormattersManager.java:664) + at org.eclipse.jdt.internal.debug.core.model.JDIThread.runEvaluation(JDIThread.java:828) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.valueToString(JavaDetailFormattersManager.java:673) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.resolveFormatter(JavaDetailFormattersManager.java:167) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.access$1(JavaDetailFormattersManager.java:140) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$1.run(JavaDetailFormattersManager.java:135) + at org.eclipse.jdt.internal.debug.core.model.JDIThread$ThreadJob.run(JDIThread.java:3529) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.jdt.debug.ui 4 150 2017-10-08 22:41:05.736 +!MESSAGE Internal Error +!STACK 1 +org.eclipse.debug.core.DebugException: com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine occurred while retrieving array length. + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.throwDebugException(JDIDebugElement.java:263) + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.requestFailed(JDIDebugElement.java:202) + at org.eclipse.jdt.internal.debug.core.model.JDIDebugElement.targetRequestFailed(JDIDebugElement.java:182) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayValue.getLength(JDIArrayValue.java:81) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:690) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:710) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener$1.run(JavaDetailFormattersManager.java:664) + at org.eclipse.jdt.internal.debug.core.model.JDIThread.runEvaluation(JDIThread.java:828) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.valueToString(JavaDetailFormattersManager.java:673) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.resolveFormatter(JavaDetailFormattersManager.java:167) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.access$1(JavaDetailFormattersManager.java:140) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$1.run(JavaDetailFormattersManager.java:135) + at org.eclipse.jdt.internal.debug.core.model.JDIThread$ThreadJob.run(JDIThread.java:3529) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine + at org.eclipse.jdi.internal.connect.PacketSendManager.sendPacket(PacketSendManager.java:90) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:187) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:227) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:243) + at org.eclipse.jdi.internal.ArrayReferenceImpl.length(ArrayReferenceImpl.java:230) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayValue.getLength(JDIArrayValue.java:79) + ... 10 more +!SUBENTRY 1 org.eclipse.jdt.debug 4 5010 2017-10-08 22:41:05.736 +!MESSAGE com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine occurred while retrieving array length. +!STACK 0 +com.sun.jdi.VMDisconnectedException: Got IOException from Virtual Machine + at org.eclipse.jdi.internal.connect.PacketSendManager.sendPacket(PacketSendManager.java:90) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:187) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:227) + at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:243) + at org.eclipse.jdi.internal.ArrayReferenceImpl.length(ArrayReferenceImpl.java:230) + at org.eclipse.jdt.internal.debug.core.model.JDIArrayValue.getLength(JDIArrayValue.java:79) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:690) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.appendArrayDetail(JavaDetailFormattersManager.java:710) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener$1.run(JavaDetailFormattersManager.java:664) + at org.eclipse.jdt.internal.debug.core.model.JDIThread.runEvaluation(JDIThread.java:828) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$EvaluationListener.valueToString(JavaDetailFormattersManager.java:673) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.resolveFormatter(JavaDetailFormattersManager.java:167) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager.access$1(JavaDetailFormattersManager.java:140) + at org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager$1.run(JavaDetailFormattersManager.java:135) + at org.eclipse.jdt.internal.debug.core.model.JDIThread$ThreadJob.run(JDIThread.java:3529) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.ui 4 0 2017-10-08 22:52:16.563 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 22:52:28.829 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-08 22:55:44.385 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 01:42:31.622 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 01:42:32.291 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 01:53:44.394 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 01:56:35.987 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:04:30.789 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:07:12.138 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:10:03.258 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more +!SESSION 2017-10-09 02:11:30.771 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-09 02:12:04.493 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:14:12.657 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:40:11.410 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:40:15.524 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:40:15.983 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.jface.text 2 0 2017-10-09 02:49:24.380 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-09 02:49:24.381 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.recommenders.models.rcp 1 11 2017-10-09 02:49:25.997 +!MESSAGE The model index service was accessed either before it started or after it finished running. +!STACK 0 +org.eclipse.recommenders.utils.Logs$LogTraceException + at org.eclipse.recommenders.utils.Logs$LogTraceException.newTrace(Logs.java:381) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:134) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:126) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelIndex.suggest(EclipseModelIndex.java:211) + at org.eclipse.recommenders.models.SimpleModelProvider.acquireModel(SimpleModelProvider.java:70) + at org.eclipse.recommenders.models.PoolingModelProvider.access$0(PoolingModelProvider.java:1) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:96) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:1) + at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1220) + at org.eclipse.recommenders.models.PoolingModelProvider.acquireModel(PoolingModelProvider.java:67) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:65) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:1) + at org.eclipse.recommenders.internal.models.rcp.PrefetchModelArchiveJob.run(PrefetchModelArchiveJob.java:43) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:49:46.268 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:55:47.677 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:55:55.175 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 02:55:55.635 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 03:19:46.116 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: Graphic is disposed + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.Font.getFontData(Font.java:192) + at org.eclipse.swt.custom.CTabFolderRenderer.drawChevron(CTabFolderRenderer.java:909) + at org.eclipse.swt.custom.CTabFolderRenderer.draw(CTabFolderRenderer.java:605) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.draw(CTabRendering.java:251) + at org.eclipse.swt.custom.CTabFolder.createButtonImage(CTabFolder.java:747) + at org.eclipse.swt.custom.CTabFolder.setButtonBounds(CTabFolder.java:2561) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3786) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3717) + at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2110) + at org.eclipse.swt.custom.CTabFolder.lambda$0(CTabFolder.java:335) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.sendResize(Control.java:3087) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1035) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1007) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:973) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1187) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1778) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1850) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1188) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:172) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:935) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:863) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:858) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:842) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:328) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.preWindowShellClose(IDEWorkbenchWindowAdvisor.java:168) + at org.eclipse.ui.internal.WorkbenchWindow$6.close(WorkbenchWindow.java:530) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer$3.shellClosed(WBWRenderer.java:615) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:99) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1088) + at org.eclipse.swt.widgets.Decorations.closeWidget(Decorations.java:316) + at org.eclipse.swt.widgets.Decorations.WM_CLOSE(Decorations.java:1729) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4845) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2560) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3815) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.e4.ui.css.swt.theme 4 0 2017-10-09 03:19:46.209 +!MESSAGE Graphic is disposed +!STACK 0 +org.eclipse.swt.SWTException: Graphic is disposed + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.Font.getFontData(Font.java:192) + at org.eclipse.e4.ui.css.swt.helpers.CSSSWTFontHelper.getFirstFontData(CSSSWTFontHelper.java:459) + at org.eclipse.e4.ui.css.swt.properties.converters.CSSValueSWTFontDataConverterImpl.convert(CSSValueSWTFontDataConverterImpl.java:59) + at org.eclipse.e4.ui.css.swt.properties.converters.CSSValueSWTFontConverterImpl.convert(CSSValueSWTFontConverterImpl.java:34) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.convert(AbstractCSSEngine.java:1124) + at org.eclipse.e4.ui.css.swt.properties.css2.CSSPropertyFontSWTHandler.onAllCSSPropertiesApplyed(CSSPropertyFontSWTHandler.java:251) + at org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler2.onAllCSSPropertiesApplyed(ICSSPropertyHandler2.java:44) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.applyStyleDeclaration(AbstractCSSEngine.java:581) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.applyStyles(AbstractCSSEngine.java:426) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.applyStyles(AbstractCSSEngine.java:367) + at org.eclipse.e4.ui.css.swt.engine.CSSSWTApplyStylesListener$1.handleEvent(CSSSWTApplyStylesListener.java:32) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.runSkin(Display.java:4321) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1361) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1007) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:973) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1187) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1778) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1850) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1188) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:172) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:935) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:863) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:858) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:842) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:328) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.preWindowShellClose(IDEWorkbenchWindowAdvisor.java:168) + at org.eclipse.ui.internal.WorkbenchWindow$6.close(WorkbenchWindow.java:530) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer$3.shellClosed(WBWRenderer.java:615) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:99) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1088) + at org.eclipse.swt.widgets.Decorations.closeWidget(Decorations.java:316) + at org.eclipse.swt.widgets.Decorations.WM_CLOSE(Decorations.java:1729) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4845) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2560) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3815) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.ui 4 0 2017-10-09 03:19:46.298 +!MESSAGE Unhandled event loop exception +!STACK 0 +java.lang.NullPointerException + at org.eclipse.ui.internal.NavigationHistory.getDisplay(NavigationHistory.java:176) + at org.eclipse.ui.internal.NavigationHistory.markEditor(NavigationHistory.java:193) + at org.eclipse.ui.internal.WorkbenchPage.updateActiveEditorSources(WorkbenchPage.java:418) + at org.eclipse.ui.internal.WorkbenchPage.firePartClosed(WorkbenchPage.java:5177) + at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.lambda$0(CompatibilityPart.java:104) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Canvas.releaseChildren(Canvas.java:171) + at org.eclipse.swt.widgets.Decorations.releaseChildren(Decorations.java:808) + at org.eclipse.swt.widgets.Shell.releaseChildren(Shell.java:1368) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.preWindowShellClose(IDEWorkbenchWindowAdvisor.java:168) + at org.eclipse.ui.internal.WorkbenchWindow$6.close(WorkbenchWindow.java:530) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer$3.shellClosed(WBWRenderer.java:615) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:99) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1088) + at org.eclipse.swt.widgets.Decorations.closeWidget(Decorations.java:316) + at org.eclipse.swt.widgets.Decorations.WM_CLOSE(Decorations.java:1729) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4845) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2560) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3815) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +!SESSION 2017-10-09 03:26:53.247 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.core.resources 2 10035 2017-10-09 03:27:59.231 +!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. +!SESSION 2017-10-09 03:28:15.680 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.core.resources 2 10035 2017-10-09 03:28:19.039 +!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-09 03:29:00.768 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.ui 4 0 2017-10-09 03:29:48.307 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 03:29:50.051 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.jface.text 2 0 2017-10-09 03:35:50.141 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-09 03:35:50.142 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.recommenders.models.rcp 1 11 2017-10-09 03:35:51.579 +!MESSAGE The model index service was accessed either before it started or after it finished running. +!STACK 0 +org.eclipse.recommenders.utils.Logs$LogTraceException + at org.eclipse.recommenders.utils.Logs$LogTraceException.newTrace(Logs.java:381) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:134) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:126) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelIndex.suggest(EclipseModelIndex.java:211) + at org.eclipse.recommenders.models.SimpleModelProvider.acquireModel(SimpleModelProvider.java:70) + at org.eclipse.recommenders.models.PoolingModelProvider.access$0(PoolingModelProvider.java:1) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:96) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:1) + at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1220) + at org.eclipse.recommenders.models.PoolingModelProvider.acquireModel(PoolingModelProvider.java:67) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:65) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:1) + at org.eclipse.recommenders.internal.models.rcp.PrefetchModelArchiveJob.run(PrefetchModelArchiveJob.java:43) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.ui 4 0 2017-10-09 03:47:44.309 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 03:47:44.745 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more +!SESSION 2017-10-09 03:58:11.782 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-09 03:58:20.895 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.ui 4 0 2017-10-09 04:28:57.719 +!MESSAGE Unhandled event loop exception +!STACK 0 +java.lang.IllegalArgumentException: Argument not valid + at org.eclipse.swt.SWT.error(SWT.java:4514) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.GC.setForeground(GC.java:4639) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.drawBackground(CTabRendering.java:1075) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.drawUnselectedTabBackground(CTabRendering.java:1008) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.drawCustomBackground(CTabRendering.java:990) + at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.draw(CTabRendering.java:218) + at org.eclipse.swt.custom.CTabFolder.updateBkImages(CTabFolder.java:3876) + at org.eclipse.swt.custom.CTabFolder.setButtonBounds(CTabFolder.java:2611) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3786) + at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3717) + at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2110) + at org.eclipse.swt.custom.CTabFolder.lambda$0(CTabFolder.java:335) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.sendResize(Control.java:3087) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1035) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1007) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:973) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1187) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1778) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1850) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1188) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:172) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:935) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:863) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:858) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:842) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:328) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.e4.ui.css.swt.theme 4 0 2017-10-09 04:28:57.722 +!MESSAGE Graphic is disposed +!STACK 0 +org.eclipse.swt.SWTException: Graphic is disposed + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.SWT.error(SWT.java:4419) + at org.eclipse.swt.graphics.Font.getFontData(Font.java:192) + at org.eclipse.e4.ui.css.swt.helpers.CSSSWTFontHelper.getFirstFontData(CSSSWTFontHelper.java:459) + at org.eclipse.e4.ui.css.swt.properties.converters.CSSValueSWTFontDataConverterImpl.convert(CSSValueSWTFontDataConverterImpl.java:59) + at org.eclipse.e4.ui.css.swt.properties.converters.CSSValueSWTFontConverterImpl.convert(CSSValueSWTFontConverterImpl.java:34) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.convert(AbstractCSSEngine.java:1124) + at org.eclipse.e4.ui.css.swt.properties.css2.CSSPropertyFontSWTHandler.onAllCSSPropertiesApplyed(CSSPropertyFontSWTHandler.java:251) + at org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler2.onAllCSSPropertiesApplyed(ICSSPropertyHandler2.java:44) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.applyStyleDeclaration(AbstractCSSEngine.java:581) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.applyStyles(AbstractCSSEngine.java:426) + at org.eclipse.e4.ui.css.core.impl.engine.AbstractCSSEngine.applyStyles(AbstractCSSEngine.java:367) + at org.eclipse.e4.ui.css.swt.engine.CSSSWTApplyStylesListener$1.handleEvent(CSSSWTApplyStylesListener.java:32) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.runSkin(Display.java:4321) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1361) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1039) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1085) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3337) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3333) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:283) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:228) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:271) + at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:145) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) + at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3304) + at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1079) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3265) + at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3261) + at org.eclipse.swt.widgets.Control.setBounds(Control.java:3256) + at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) + at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1363) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1774) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1007) + at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:973) + at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1187) + at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1778) + at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) + at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1850) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4918) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5743) + at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4931) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) + at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1188) + at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) + at org.eclipse.swt.widgets.Widget.release(Widget.java:844) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:172) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:935) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:863) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:858) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:842) + at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:328) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.ui 4 0 2017-10-09 04:28:57.782 +!MESSAGE Unhandled event loop exception +!STACK 0 +java.lang.NullPointerException + at org.eclipse.ui.internal.NavigationHistory.getDisplay(NavigationHistory.java:176) + at org.eclipse.ui.internal.NavigationHistory.markEditor(NavigationHistory.java:193) + at org.eclipse.ui.internal.WorkbenchPage.updateActiveEditorSources(WorkbenchPage.java:418) + at org.eclipse.ui.internal.WorkbenchPage.firePartClosed(WorkbenchPage.java:5177) + at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.lambda$0(CompatibilityPart.java:104) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:147) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.lambda$0(SWTPartRenderer.java:136) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.release(Widget.java:836) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:929) + at org.eclipse.swt.widgets.Canvas.releaseChildren(Canvas.java:171) + at org.eclipse.swt.widgets.Decorations.releaseChildren(Decorations.java:808) + at org.eclipse.swt.widgets.Shell.releaseChildren(Shell.java:1368) + at org.eclipse.swt.widgets.Widget.release(Widget.java:839) + at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) + at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:460) + at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) + at org.eclipse.swt.widgets.Display.release(Display.java:3868) + at org.eclipse.swt.graphics.Device.dispose(Device.java:298) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3351) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:224) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:164) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4420) + at org.eclipse.swt.widgets.Display.messageProc(Display.java:3364) + at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2555) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4941) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5191) + at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) + at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3152) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3812) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +!SESSION 2017-10-09 12:23:22.766 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.core.resources 2 10035 2017-10-09 12:24:05.736 +!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-09 12:24:39.357 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-10-09 13:24:15.330 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-09 13:24:15.340 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.recommenders.models.rcp 1 11 2017-10-09 13:24:17.325 +!MESSAGE The model index service was accessed either before it started or after it finished running. +!STACK 0 +org.eclipse.recommenders.utils.Logs$LogTraceException + at org.eclipse.recommenders.utils.Logs$LogTraceException.newTrace(Logs.java:381) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:134) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:126) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelIndex.suggest(EclipseModelIndex.java:211) + at org.eclipse.recommenders.models.SimpleModelProvider.acquireModel(SimpleModelProvider.java:70) + at org.eclipse.recommenders.models.PoolingModelProvider.access$0(PoolingModelProvider.java:1) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:96) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:1) + at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1220) + at org.eclipse.recommenders.models.PoolingModelProvider.acquireModel(PoolingModelProvider.java:67) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:65) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:1) + at org.eclipse.recommenders.internal.models.rcp.PrefetchModelArchiveJob.run(PrefetchModelArchiveJob.java:43) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:26:12.746 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:46:46.332 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:46:47.154 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:47:00.323 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more diff --git a/.metadata/.log b/.metadata/.log index 7ee3c95..3ab478e 100644 --- a/.metadata/.log +++ b/.metadata/.log @@ -1,3697 +1,7060 @@ -!SESSION 2017-03-21 20:36:59.126 ----------------------------------------------- -eclipse.buildId=4.6.2.M20161124-1400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-03-21 20:37:57.050 +!SESSION 2017-10-09 12:23:22.766 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +This is a continuation of log file E:\Study\java\judt\.metadata\.bak_0.log +Created Time: 2017-10-09 13:47:08.029 + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:47:08.029 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:49:08.542 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:49:09.058 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:50:54.108 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:52:17.664 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 13:52:18.280 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 14:13:10.983 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 14:17:09.379 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 14:29:14.333 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 14:29:34.591 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 14:38:32.078 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 14:38:32.671 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 14:57:37.419 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 14:57:38.125 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 15:02:50.589 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.jface.text 2 0 2017-10-09 15:55:44.589 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-09 15:55:44.636 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.ui 4 0 2017-10-09 16:03:33.835 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 16:13:24.643 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 16:57:04.155 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 16:57:05.015 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 16:57:26.566 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 17:14:09.785 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 17:14:10.390 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 17:14:13.253 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 17:14:13.847 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:00:20.847 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:00:31.569 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:00:32.007 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:07:57.792 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:15:07.934 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:15:08.455 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:16:53.709 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:16:54.167 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:18:38.417 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:18:42.380 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:20:06.052 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:33:51.137 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:33:51.747 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:39:24.811 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:41:45.570 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:41:46.128 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 18:58:17.033 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 19:06:34.863 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 19:34:28.184 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 19:34:33.965 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 19:38:44.884 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 19:38:45.444 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 19:41:48.159 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 19:42:06.203 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 19:42:06.581 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-09 19:47:48.991 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more +!SESSION 2017-10-09 22:24:42.294 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-09 22:26:41.384 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-03-22 19:42:10.566 ----------------------------------------------- -eclipse.buildId=4.6.2.M20161124-1400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-03-22 19:43:05.670 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 01:05:25.880 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 01:05:25.881 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.recommenders.models.rcp 1 11 2017-10-10 01:05:27.692 +!MESSAGE The model index service was accessed either before it started or after it finished running. +!STACK 0 +org.eclipse.recommenders.utils.Logs$LogTraceException + at org.eclipse.recommenders.utils.Logs$LogTraceException.newTrace(Logs.java:381) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:134) + at org.eclipse.recommenders.utils.Logs.log(Logs.java:126) + at org.eclipse.recommenders.internal.models.rcp.EclipseModelIndex.suggest(EclipseModelIndex.java:211) + at org.eclipse.recommenders.models.SimpleModelProvider.acquireModel(SimpleModelProvider.java:70) + at org.eclipse.recommenders.models.PoolingModelProvider.access$0(PoolingModelProvider.java:1) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:96) + at org.eclipse.recommenders.models.PoolingModelProvider$ModelPoolFactoryMediator.makeObject(PoolingModelProvider.java:1) + at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1220) + at org.eclipse.recommenders.models.PoolingModelProvider.acquireModel(PoolingModelProvider.java:67) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:65) + at org.eclipse.recommenders.internal.calls.rcp.RcpCallModelProvider.acquireModel(RcpCallModelProvider.java:1) + at org.eclipse.recommenders.internal.models.rcp.PrefetchModelArchiveJob.run(PrefetchModelArchiveJob.java:43) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +!SESSION 2017-10-10 01:50:34.552 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 01:50:46.886 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-03-22 20:24:11.451 ----------------------------------------------- -eclipse.buildId=4.6.2.M20161124-1400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-03-22 20:25:27.553 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 02:20:50.867 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 02:20:50.867 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' +!SESSION 2017-10-10 02:29:51.177 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 02:30:07.325 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-03-24 02:26:49.142 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-03-24 02:28:34.087 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 03:38:20.386 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 03:38:20.388 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' +!SESSION 2017-10-10 12:56:08.786 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 13:00:43.436 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.e4.ui.workbench 2 0 2017-03-24 02:28:35.379 -!MESSAGE Removing part descriptor with the 'org.eclipse.wb.core.StructureView' id and the 'Structure' description. Points to the invalid 'bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView' class. - -!ENTRY org.eclipse.e4.ui.workbench 2 0 2017-03-24 02:28:35.380 -!MESSAGE Removing part descriptor with the 'org.eclipse.wb.core.PaletteView' id and the 'Palette' description. Points to the invalid 'bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView' class. - -!ENTRY org.eclipse.equinox.p2.transport.ecf 2 0 2017-03-24 02:50:40.841 -!MESSAGE Connection to http://mirror.ufs.ac.za/eclipse/releases/neon/201612211000/features/org.eclipse.wb.core.java.feature_1.9.0.jar failed on Connection timed out: connect. Retry attempt 0 started -!STACK 0 -java.net.ConnectException: Connection timed out: connect - at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) - at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) - at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) - at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) - at java.net.AbstractPlainSocketImpl.connect(Unknown Source) - at java.net.PlainSocketImpl.connect(Unknown Source) - at java.net.SocksSocketImpl.connect(Unknown Source) - at java.net.Socket.connect(Unknown Source) - at org.eclipse.ecf.internal.provider.filetransfer.httpclient4.ECFHttpClientProtocolSocketFactory.connectSocket(ECFHttpClientProtocolSocketFactory.java:86) - at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:177) - at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144) - at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:131) - at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:611) - at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:446) - at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863) - at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) - at org.eclipse.ecf.provider.filetransfer.httpclient4.HttpClientRetrieveFileTransfer.performConnect(HttpClientRetrieveFileTransfer.java:1084) - at org.eclipse.ecf.provider.filetransfer.httpclient4.HttpClientRetrieveFileTransfer.access$0(HttpClientRetrieveFileTransfer.java:1075) - at org.eclipse.ecf.provider.filetransfer.httpclient4.HttpClientRetrieveFileTransfer$1.performFileTransfer(HttpClientRetrieveFileTransfer.java:1071) - at org.eclipse.ecf.filetransfer.FileTransferJob.run(FileTransferJob.java:74) - at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) -!SESSION 2017-03-24 03:12:38.610 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product -data file:/D:/jinyu/udt-java/ -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-03-24 08:01:57.906 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2017-10-10 13:42:15.633 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 13:42:25.865 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-03-24 08:05:50.970 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -product org.eclipse.epp.package.jee.product -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product -product org.eclipse.epp.package.jee.product -data file:/D:/jinyu/udt-java/ -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-03-24 08:06:24.151 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 13:56:22.280 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 13:56:22.281 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.ui 4 0 2017-10-10 16:54:00.854 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 16:54:25.730 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 16:54:26.169 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 17:03:56.819 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 17:04:00.948 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 17:40:17.833 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 17:40:47.310 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-10 17:40:47.312 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.ui 4 0 2017-10-10 18:12:36.668 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 18:12:56.341 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 18:15:18.030 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 18:26:10.217 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 18:26:21.050 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-10 18:26:21.541 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.jdt.debug 4 125 2017-10-10 19:21:24.419 +!MESSAGE Internal error logged from JDI Debug: +!STACK 1 +org.eclipse.debug.core.DebugException: Invalid stack frame + at org.eclipse.jdt.internal.debug.core.model.JDIStackFrame.getUnderlyingStackFrame(JDIStackFrame.java:1196) + at org.eclipse.jdt.internal.debug.core.model.JDIStackFrame.getUnderlyingThisObject(JDIStackFrame.java:834) + at org.eclipse.jdt.internal.debug.core.model.JDIStackFrame.getThis(JDIStackFrame.java:1250) + at org.eclipse.jdt.internal.debug.ui.JavaDebugHover.getHoverInfo2(JavaDebugHover.java:372) + at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:164) + at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:130) + at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:86) + at org.eclipse.jface.text.TextViewerHoverManager$4.run(TextViewerHoverManager.java:166) +!SUBENTRY 1 org.eclipse.jdt.debug 4 100 2017-10-10 19:21:24.479 +!MESSAGE Invalid stack frame +!SESSION 2017-10-10 22:45:03.292 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.e4.ui.workbench 4 0 2017-10-10 22:49:11.958 +!MESSAGE Unable to load resource file:/E:/Study/java/judt/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi +!STACK 0 +org.eclipse.emf.ecore.resource.impl.ResourceSetImpl$1DiagnosticWrappedException: org.xml.sax.SAXParseExceptionpublicId: file:/E:/Study/java/judt/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi; systemId: file:/E:/Study/java/judt/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.handleDemandLoadException(ResourceSetImpl.java:319) + at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:278) + at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResource(ResourceSetImpl.java:406) + at org.eclipse.e4.ui.internal.workbench.ResourceHandler.getResource(ResourceHandler.java:286) + at org.eclipse.e4.ui.internal.workbench.ResourceHandler.loadResource(ResourceHandler.java:262) + at org.eclipse.e4.ui.internal.workbench.ResourceHandler.loadMostRecentModel(ResourceHandler.java:169) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application.loadApplicationModel(E4Application.java:378) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createE4Workbench(E4Application.java:253) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:614) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.xml.sax.SAXParseExceptionpublicId: file:/E:/Study/java/judt/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi; systemId: file:/E:/Study/java/judt/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(Unknown Source) + at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(XMLLoadImpl.java:175) + at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLResourceImpl.java:261) + at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1518) + at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1297) + at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoad(ResourceSetImpl.java:259) + at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:274) + ... 23 more + +!ENTRY org.eclipse.e4.ui.workbench 4 0 2017-10-10 22:49:12.988 +!MESSAGE The persisted application model has no top-level window. Reinitializing with the default application model. +!STACK 0 +java.lang.Exception + at org.eclipse.e4.ui.internal.workbench.ResourceHandler.loadMostRecentModel(ResourceHandler.java:174) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application.loadApplicationModel(E4Application.java:378) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createE4Workbench(E4Application.java:253) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:614) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 22:50:56.469 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-03-26 01:18:44.784 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-03-26 01:19:15.899 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jdt.ui 4 10001 2017-10-10 22:50:58.375 +!MESSAGE Internal Error +!STACK 1 +org.eclipse.jdt.internal.ui.JavaUIException: Problems reading information from XML 'OpenTypeHistory.xml' + at org.eclipse.jdt.internal.corext.util.History.createException(History.java:74) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:263) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:171) + at org.eclipse.jdt.internal.corext.util.OpenTypeHistory.(OpenTypeHistory.java:200) + at org.eclipse.jdt.internal.corext.util.OpenTypeHistory.getInstance(OpenTypeHistory.java:186) + at org.eclipse.jdt.internal.ui.JavaPlugin.initializeAfterLoad(JavaPlugin.java:420) + at org.eclipse.jdt.internal.ui.InitializeAfterLoadJob$RealJob.run(InitializeAfterLoadJob.java:37) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:261) + ... 6 more +!SUBENTRY 1 org.eclipse.jdt.ui 4 4 2017-10-10 22:50:58.375 +!MESSAGE Problems reading information from XML 'OpenTypeHistory.xml' +!STACK 0 +org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:261) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:171) + at org.eclipse.jdt.internal.corext.util.OpenTypeHistory.(OpenTypeHistory.java:200) + at org.eclipse.jdt.internal.corext.util.OpenTypeHistory.getInstance(OpenTypeHistory.java:186) + at org.eclipse.jdt.internal.ui.JavaPlugin.initializeAfterLoad(JavaPlugin.java:420) + at org.eclipse.jdt.internal.ui.InitializeAfterLoadJob$RealJob.run(InitializeAfterLoadJob.java:37) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.jdt.ui 4 10001 2017-10-10 22:51:46.179 +!MESSAGE Internal Error +!STACK 1 +org.eclipse.jdt.internal.ui.JavaUIException: Problems reading information from XML 'QualifiedTypeNameHistory.xml' + at org.eclipse.jdt.internal.corext.util.History.createException(History.java:74) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:263) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:171) + at org.eclipse.jdt.internal.corext.util.QualifiedTypeNameHistory.(QualifiedTypeNameHistory.java:33) + at org.eclipse.jdt.internal.corext.util.QualifiedTypeNameHistory.getDefault(QualifiedTypeNameHistory.java:26) + at org.eclipse.jdt.internal.ui.JavaPlugin.stop(JavaPlugin.java:511) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) +Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:261) + ... 21 more +!SUBENTRY 1 org.eclipse.jdt.ui 4 4 2017-10-10 22:51:46.180 +!MESSAGE Problems reading information from XML 'QualifiedTypeNameHistory.xml' +!STACK 0 +org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:261) + at org.eclipse.jdt.internal.corext.util.History.load(History.java:171) + at org.eclipse.jdt.internal.corext.util.QualifiedTypeNameHistory.(QualifiedTypeNameHistory.java:33) + at org.eclipse.jdt.internal.corext.util.QualifiedTypeNameHistory.getDefault(QualifiedTypeNameHistory.java:26) + at org.eclipse.jdt.internal.ui.JavaPlugin.stop(JavaPlugin.java:511) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) + +!ENTRY org.eclipse.core.jobs 4 2 2017-10-10 22:51:46.790 +!MESSAGE An internal error occurred during: "Setting VM arguments". +!STACK 0 +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.getLocation(ProfileBundleContainer.java:73) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.getVMArguments(AbstractBundleContainer.java:230) + at org.eclipse.pde.internal.core.target.TargetPlatformService.getVMArguments(TargetPlatformService.java:637) + at org.eclipse.pde.internal.core.target.TargetPlatformService.access$0(TargetPlatformService.java:634) + at org.eclipse.pde.internal.core.target.TargetPlatformService$2.run(TargetPlatformService.java:617) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.pde.core 4 0 2017-10-10 22:51:46.842 +!MESSAGE FrameworkEvent ERROR +!STACK 0 +org.osgi.framework.BundleException: Exception in org.eclipse.pde.internal.core.PDECore.stop() of bundle org.eclipse.pde.core. + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:855) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) +Caused by: java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + ... 13 more +Root exception: +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) + +!ENTRY org.eclipse.core.jobs 2 2 2017-10-10 22:51:50.172 +!MESSAGE Job found still running after platform shutdown. Jobs should be canceled by the plugin that scheduled them during shutdown: org.eclipse.ui.internal.Workbench$40 +!SESSION 2017-10-10 22:52:09.509 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 22:52:17.569 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-03-26 11:08:10.027 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-03-26 11:09:44.150 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.debug.ui 4 120 2017-10-10 22:52:24.850 +!MESSAGE Error logged from Debug UI: +!STACK 0 +org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.restoreLaunchHistory(LaunchConfigurationManager.java:501) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.loadLaunchHistories(LaunchConfigurationManager.java:1066) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.getLaunchHistory(LaunchConfigurationManager.java:1038) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.internalGetHistory(AbstractLaunchHistoryAction.java:547) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.getToolTip(AbstractLaunchHistoryAction.java:233) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.updateTooltip(AbstractLaunchHistoryAction.java:198) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.initialize(AbstractLaunchHistoryAction.java:168) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.selectionChanged(AbstractLaunchHistoryAction.java:513) + at org.eclipse.ui.internal.PluginAction.refreshEnablement(PluginAction.java:206) + at org.eclipse.ui.internal.PluginAction.createDelegate(PluginAction.java:126) + at org.eclipse.ui.internal.WWinPluginAction.refreshActionList(WWinPluginAction.java:158) + at org.eclipse.ui.plugin.AbstractUIPlugin.lambda$0(AbstractUIPlugin.java:481) + at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:37) + at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) + at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4213) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3820) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:424) + at org.eclipse.jface.dialogs.MessageDialog.openInformation(MessageDialog.java:534) + at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:229) + at org.eclipse.ui.internal.WWinPluginAction.runWithEvent(WWinPluginAction.java:219) + at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:565) + at org.eclipse.jface.action.ActionContributionItem.lambda$5(ActionContributionItem.java:436) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4238) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3817) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.pde.core 4 0 2017-10-10 22:52:30.865 +!MESSAGE FrameworkEvent ERROR +!STACK 0 +org.osgi.framework.BundleException: Exception in org.eclipse.pde.internal.core.PDECore.stop() of bundle org.eclipse.pde.core. + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:855) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) +Caused by: java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + ... 13 more +Root exception: +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) + +!ENTRY org.eclipse.core.jobs 4 2 2017-10-10 22:52:30.870 +!MESSAGE An internal error occurred during: "Setting VM arguments". +!STACK 0 +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.getLocation(ProfileBundleContainer.java:73) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.getVMArguments(AbstractBundleContainer.java:230) + at org.eclipse.pde.internal.core.target.TargetPlatformService.getVMArguments(TargetPlatformService.java:637) + at org.eclipse.pde.internal.core.target.TargetPlatformService.access$0(TargetPlatformService.java:634) + at org.eclipse.pde.internal.core.target.TargetPlatformService$2.run(TargetPlatformService.java:617) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +!SESSION 2017-10-10 22:52:47.857 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 22:52:59.813 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-02 01:59:50.264 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-02 02:00:08.715 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.pde.core 4 0 2017-10-10 22:54:22.404 +!MESSAGE FrameworkEvent ERROR +!STACK 0 +org.osgi.framework.BundleException: Exception in org.eclipse.pde.internal.core.PDECore.stop() of bundle org.eclipse.pde.core. + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:855) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) +Caused by: java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + ... 13 more +Root exception: +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) + +!ENTRY org.eclipse.core.jobs 4 2 2017-10-10 22:54:22.410 +!MESSAGE An internal error occurred during: "Setting VM arguments". +!STACK 0 +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.getLocation(ProfileBundleContainer.java:73) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.getVMArguments(AbstractBundleContainer.java:230) + at org.eclipse.pde.internal.core.target.TargetPlatformService.getVMArguments(TargetPlatformService.java:637) + at org.eclipse.pde.internal.core.target.TargetPlatformService.access$0(TargetPlatformService.java:634) + at org.eclipse.pde.internal.core.target.TargetPlatformService$2.run(TargetPlatformService.java:617) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +!SESSION 2017-10-10 22:54:05.165 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 22:54:36.685 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.epp.logging.aeri.ide 2 17 2017-04-02 02:00:13.612 -!MESSAGE Server 鈥榦rg.eclipse.epp.logging.aeri.ide.server鈥 failed with exception: Connect to dev.eclipse.org:443 [dev.eclipse.org/198.41.30.200] failed: Read timed out. ; version: 2.0.4.v20170307-1435 -!STACK 0 -org.apache.http.conn.ConnectTimeoutException: Connect to dev.eclipse.org:443 [dev.eclipse.org/198.41.30.200] failed: Read timed out - at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:134) - at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:319) - at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363) - at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219) - at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195) - at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86) - at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) - at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) - at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) - at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57) - at org.apache.http.client.fluent.Executor.execute(Executor.java:206) - at org.eclipse.epp.internal.logging.aeri.ide.server.mars.IO.request(IO.java:206) - at org.eclipse.epp.internal.logging.aeri.ide.server.mars.IO.refreshConfiguration(IO.java:68) - at org.eclipse.epp.internal.logging.aeri.ide.server.mars.ServerConnection.startUp(ServerConnection.java:124) - at com.google.common.util.concurrent.AbstractIdleService$2$1.run(AbstractIdleService.java:54) - at com.google.common.util.concurrent.Callables$3.run(Callables.java:93) - at java.lang.Thread.run(Thread.java:745) -Caused by: java.net.SocketTimeoutException: Read timed out - at java.net.SocketInputStream.socketRead0(Native Method) - at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) - at java.net.SocketInputStream.read(SocketInputStream.java:171) - at java.net.SocketInputStream.read(SocketInputStream.java:141) - at sun.security.ssl.InputRecord.readFully(InputRecord.java:465) - at sun.security.ssl.InputRecord.read(InputRecord.java:503) - at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973) - at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) - at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) - at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) - at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:290) - at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:259) - at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:125) - ... 16 more - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-02 03:51:07.175 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/widget/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl@18ad543b (elementId: org.eclipse.e4.ui.compatibility.editor, tags: [Editor, org.eclipse.jdt.ui.CompilationUnitEditor, removeOnHide], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer@56ed9270, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (contributionURI: bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor, object: org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor@7aadd290, context: PartImpl (org.eclipse.e4.ui.compatibility.editor) Context, variables: [], label: UDTServerSocket.java, iconURI: platform:/plugin/org.eclipse.jdt.ui/icons/full/obj16/jcu_obj.png, tooltip: null, dirty: false, closeable: true, description: null), Widget=null, org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl@18ad543b (elementId: org.eclipse.e4.ui.compatibility.editor, tags: [Editor, org.eclipse.jdt.ui.CompilationUnitEditor, removeOnHide], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer@56ed9270, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (contributionURI: bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor, object: org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor@7aadd290, context: PartImpl (org.eclipse.e4.ui.compatibility.editor) Context, variables: [], label: UDTServerSocket.java, iconURI: platform:/plugin/org.eclipse.jdt.ui/icons/full/obj16/jcu_obj.png, tooltip: null, dirty: false, closeable: true, description: null), AttName=widget, EventType=SET, OldValue=ContributedPartRenderer$2 {}, Widget=null}, AttName=widget, EventType=SET, OldValue=ContributedPartRenderer$2 {}} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@4ab909f4 -!STACK 0 -java.lang.NullPointerException - at org.eclipse.ui.internal.NavigationHistory.getDisplay(NavigationHistory.java:176) - at org.eclipse.ui.internal.NavigationHistory.markEditor(NavigationHistory.java:193) - at org.eclipse.ui.internal.WorkbenchPage.updateActiveEditorSources(WorkbenchPage.java:411) - at org.eclipse.ui.internal.WorkbenchPage.firePartClosed(WorkbenchPage.java:5164) - at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart$1.handleEvent(CompatibilityPart.java:102) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Widget.release(Widget.java:836) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Canvas.releaseChildren(Canvas.java:171) - at org.eclipse.swt.widgets.Decorations.releaseChildren(Decorations.java:807) - at org.eclipse.swt.widgets.Shell.releaseChildren(Shell.java:1368) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) - at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) - at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) - at org.eclipse.swt.widgets.Display.release(Display.java:3875) - at org.eclipse.swt.graphics.Device.dispose(Device.java:298) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) - at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) - at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) - at org.eclipse.jface.window.Window.open(Window.java:794) - at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) - at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -!SESSION 2017-04-02 14:35:06.822 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-02 14:35:48.921 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.debug.ui 4 120 2017-10-10 22:54:40.332 +!MESSAGE Error logged from Debug UI: +!STACK 0 +org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.restoreLaunchHistory(LaunchConfigurationManager.java:501) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.loadLaunchHistories(LaunchConfigurationManager.java:1066) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.getLaunchHistory(LaunchConfigurationManager.java:1038) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.internalGetHistory(AbstractLaunchHistoryAction.java:547) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.getToolTip(AbstractLaunchHistoryAction.java:233) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.updateTooltip(AbstractLaunchHistoryAction.java:198) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.initialize(AbstractLaunchHistoryAction.java:168) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.selectionChanged(AbstractLaunchHistoryAction.java:513) + at org.eclipse.ui.internal.PluginAction.refreshEnablement(PluginAction.java:206) + at org.eclipse.ui.internal.PluginAction.createDelegate(PluginAction.java:126) + at org.eclipse.ui.internal.WWinPluginAction.refreshActionList(WWinPluginAction.java:158) + at org.eclipse.ui.plugin.AbstractUIPlugin.lambda$0(AbstractUIPlugin.java:481) + at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:37) + at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) + at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4213) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3820) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:424) + at org.eclipse.jface.dialogs.MessageDialog.openInformation(MessageDialog.java:534) + at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:229) + at org.eclipse.ui.internal.WWinPluginAction.runWithEvent(WWinPluginAction.java:219) + at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:565) + at org.eclipse.jface.action.ActionContributionItem.lambda$5(ActionContributionItem.java:436) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4238) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3817) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.pde.core 4 0 2017-10-10 22:55:15.557 +!MESSAGE FrameworkEvent ERROR +!STACK 0 +org.osgi.framework.BundleException: Exception in org.eclipse.pde.internal.core.PDECore.stop() of bundle org.eclipse.pde.core. + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:855) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) +Caused by: java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + ... 13 more +Root exception: +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) + +!ENTRY org.eclipse.core.jobs 4 2 2017-10-10 22:55:15.562 +!MESSAGE An internal error occurred during: "Setting VM arguments". +!STACK 0 +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.getLocation(ProfileBundleContainer.java:73) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.getVMArguments(AbstractBundleContainer.java:230) + at org.eclipse.pde.internal.core.target.TargetPlatformService.getVMArguments(TargetPlatformService.java:637) + at org.eclipse.pde.internal.core.target.TargetPlatformService.access$0(TargetPlatformService.java:634) + at org.eclipse.pde.internal.core.target.TargetPlatformService$2.run(TargetPlatformService.java:617) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +!SESSION 2017-10-10 22:55:16.423 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product -data E:\Study\java\judt -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 22:55:23.208 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.e4.ui.workbench 4 0 2017-04-02 18:56:14.941 -!MESSAGE Error disposing widget for : org.eclipse.e4.ui.model.application.ui.menu.impl.MenuImpl null -!STACK 0 -org.eclipse.swt.SWTException: Graphic is disposed - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.SWT.error(SWT.java:4419) - at org.eclipse.swt.graphics.Font.getFontData(Font.java:192) - at org.eclipse.swt.custom.CTabFolderRenderer.drawChevron(CTabFolderRenderer.java:909) - at org.eclipse.swt.custom.CTabFolderRenderer.draw(CTabFolderRenderer.java:605) - at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.draw(CTabRendering.java:252) - at org.eclipse.swt.custom.CTabFolder.createButtonImage(CTabFolder.java:721) - at org.eclipse.swt.custom.CTabFolder.setButtonBounds(CTabFolder.java:2541) - at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3766) - at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3697) - at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2090) - at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:340) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.sendResize(Control.java:3042) - at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1058) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1062) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) - at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) - at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) - at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) - at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) - at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) - at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) - at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1030) - at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:996) - at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1210) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1801) - at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) - at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1849) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) - at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1187) - at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) - at org.eclipse.swt.widgets.Widget.release(Widget.java:844) - at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:176) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:918) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:846) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$3.run(PartRenderingEngine.java:841) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:825) - at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:322) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Widget.release(Widget.java:836) - at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) - at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) - at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) - at org.eclipse.swt.widgets.Display.release(Display.java:3875) - at org.eclipse.swt.graphics.Device.dispose(Device.java:298) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) - at org.eclipse.swt.internal.win32.OS.CallWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.CallWindowProc(OS.java:2446) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:483) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2197) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) - at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) - at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) - at org.eclipse.jface.window.Window.open(Window.java:794) - at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) - at org.eclipse.swt.internal.win32.OS.CallWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.CallWindowProc(OS.java:2446) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:483) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2197) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) - at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -!SESSION 2017-04-02 23:54:19.701 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-02 23:59:27.171 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.debug.ui 4 120 2017-10-10 22:55:44.706 +!MESSAGE Error logged from Debug UI: +!STACK 0 +org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.restoreLaunchHistory(LaunchConfigurationManager.java:501) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.loadLaunchHistories(LaunchConfigurationManager.java:1066) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.getLaunchHistory(LaunchConfigurationManager.java:1038) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.internalGetHistory(AbstractLaunchHistoryAction.java:547) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.getToolTip(AbstractLaunchHistoryAction.java:233) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.updateTooltip(AbstractLaunchHistoryAction.java:198) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.initialize(AbstractLaunchHistoryAction.java:168) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.selectionChanged(AbstractLaunchHistoryAction.java:513) + at org.eclipse.ui.internal.PluginAction.refreshEnablement(PluginAction.java:206) + at org.eclipse.ui.internal.PluginAction.createDelegate(PluginAction.java:126) + at org.eclipse.ui.internal.WWinPluginAction.refreshActionList(WWinPluginAction.java:158) + at org.eclipse.ui.plugin.AbstractUIPlugin.lambda$0(AbstractUIPlugin.java:481) + at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:37) + at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) + at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4213) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3820) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:424) + at org.eclipse.jface.dialogs.MessageDialog.openInformation(MessageDialog.java:534) + at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:229) + at org.eclipse.ui.internal.WWinPluginAction.runWithEvent(WWinPluginAction.java:219) + at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:565) + at org.eclipse.jface.action.ActionContributionItem.lambda$5(ActionContributionItem.java:436) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4238) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3817) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.pde.core 4 0 2017-10-10 22:55:49.354 +!MESSAGE FrameworkEvent ERROR +!STACK 0 +org.osgi.framework.BundleException: Exception in org.eclipse.pde.internal.core.PDECore.stop() of bundle org.eclipse.pde.core. + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:855) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) +Caused by: java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + ... 13 more +Root exception: +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveBundles(ProfileBundleContainer.java:94) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolve(AbstractBundleContainer.java:81) + at org.eclipse.pde.internal.core.target.TargetDefinition.resolve(TargetDefinition.java:282) + at org.eclipse.pde.internal.core.TargetPlatformHelper.getWorkspaceTargetResolved(TargetPlatformHelper.java:485) + at org.eclipse.pde.internal.core.PluginModelManager.getExternalBundles(PluginModelManager.java:615) + at org.eclipse.pde.internal.core.PluginModelManager.initializeTable(PluginModelManager.java:539) + at org.eclipse.pde.internal.core.PluginModelManager.getEntryTable(PluginModelManager.java:482) + at org.eclipse.pde.internal.core.PluginModelManager.findEntry(PluginModelManager.java:976) + at org.eclipse.pde.internal.core.PluginModelManager.findModel(PluginModelManager.java:1000) + at org.eclipse.pde.core.plugin.PluginRegistry.findModel(PluginRegistry.java:97) + at org.eclipse.pde.internal.core.JavaElementChangeListener.save(JavaElementChangeListener.java:129) + at org.eclipse.pde.internal.core.JavaElementChangeListener.shutdown(JavaElementChangeListener.java:41) + at org.eclipse.pde.internal.core.PDECore.stop(PDECore.java:312) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) + +!ENTRY org.eclipse.core.jobs 4 2 2017-10-10 22:55:49.387 +!MESSAGE An internal error occurred during: "Setting VM arguments". +!STACK 0 +java.lang.NullPointerException + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.resolveVariables(AbstractBundleContainer.java:64) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.resolveHomeLocation(ProfileBundleContainer.java:210) + at org.eclipse.pde.internal.core.target.ProfileBundleContainer.getLocation(ProfileBundleContainer.java:73) + at org.eclipse.pde.internal.core.target.AbstractBundleContainer.getVMArguments(AbstractBundleContainer.java:230) + at org.eclipse.pde.internal.core.target.TargetPlatformService.getVMArguments(TargetPlatformService.java:637) + at org.eclipse.pde.internal.core.target.TargetPlatformService.access$0(TargetPlatformService.java:634) + at org.eclipse.pde.internal.core.target.TargetPlatformService$2.run(TargetPlatformService.java:617) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +!SESSION 2017-10-10 22:57:35.640 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 22:57:44.073 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:37.584 -!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Worker-5,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Worker-5,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.getContents(ReadManager.java:145) - at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11374) - at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11346) - at org.eclipse.jdt.internal.compiler.parser.Parser.dietParse(Parser.java:9760) - at org.eclipse.jdt.internal.compiler.Compiler.internalBeginToCompile(Compiler.java:815) - at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:385) - at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:431) - at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:417) - at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:368) - at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:179) - at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:305) - at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:61) - at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:256) - at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:175) - at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:735) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206) - at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246) - at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:301) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:304) - at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:360) - at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:383) - at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144) - at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235) - at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 57 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.getContents(ReadManager.java:145) - at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11374) - at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11346) - at org.eclipse.jdt.internal.compiler.parser.Parser.dietParse(Parser.java:9760) - at org.eclipse.jdt.internal.compiler.Compiler.internalBeginToCompile(Compiler.java:815) - at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:385) - at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:431) - at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:417) - at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:368) - at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:179) - at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:305) - at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:61) - at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:256) - at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:175) - at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:735) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206) - at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246) - at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:301) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:304) - at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:360) - at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:383) - at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144) - at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235) - at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) - -!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.158 -!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 33 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) - -!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.159 -!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 33 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) - -!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.160 -!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 33 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) - -!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.161 -!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 33 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) - -!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.162 -!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 33 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) - -!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.163 -!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 33 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) - -!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.163 -!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 33 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) - -!ENTRY org.eclipse.osgi 2 0 2017-04-02 23:59:38.164 -!MESSAGE While loading class "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber", thread "Thread[Compiler Source File Reader,5,main]" timed out waiting (5007ms) for thread "Thread[Compiler Source File Reader,5,main]" to finish starting bundle "org.eclipse.wb.core_1.9.0.201608250402 [1137]". To avoid deadlock, thread "Thread[Compiler Source File Reader,5,main]" is proceeding but "org.eclipse.wb.internal.core.editor.describer.JavaSourceUiDescriber" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="1.9.0.201608250402"; osgi.identity="org.eclipse.wb.core"; singleton:="true" [id=1137] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 33 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:36) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:419) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) - at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174) - at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905) - at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243) - at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55) - at org.eclipse.core.internal.content.ContentType.getDescriber(ContentType.java:266) - at org.eclipse.core.internal.content.ContentTypeCatalog.collectMatchingByContents(ContentTypeCatalog.java:195) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:414) - at org.eclipse.core.internal.content.ContentTypeCatalog.internalFindContentTypesFor(ContentTypeCatalog.java:461) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:357) - at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:371) - at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:76) - at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:453) - at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:363) - at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:241) - at org.eclipse.core.internal.resources.File.getCharset(File.java:198) - at org.eclipse.core.internal.resources.File.getCharset(File.java:186) - at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1159) - at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79) - at org.eclipse.jdt.internal.compiler.ReadManager.run(ReadManager.java:174) - at java.lang.Thread.run(Thread.java:745) - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-03 00:13:28.827 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@5e4b9f22 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@5e4b9f22 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1cd9c2de -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-03 00:13:47.986 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@1e695be6 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@1e695be6 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1cd9c2de -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more - -!ENTRY org.eclipse.jface.text 2 0 2017-04-03 00:14:05.541 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-03 00:14:05.542 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-03 00:14:06.351 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-03 00:14:06.352 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-03 00:14:28.440 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@71bcc154 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@71bcc154 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1cd9c2de -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-03 00:14:41.129 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@4260f222 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@4260f222 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1cd9c2de -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more -!SESSION 2017-04-03 13:15:47.065 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.osgi 2 0 2017-04-03 13:20:48.672 -!MESSAGE While loading class "org.eclipse.egit.ui.internal.ConfigurationChecker$1$1", thread "Thread[Worker-0,5,main]" timed out waiting (5010ms) for thread "Thread[main,6,main]" to finish starting bundle "org.eclipse.egit.ui_4.6.1.201703071140-r [1025]". To avoid deadlock, thread "Thread[Worker-0,5,main]" is proceeding but "org.eclipse.egit.ui.internal.ConfigurationChecker$1$1" may not be fully initialized. -!STACK 0 -org.osgi.framework.BundleException: Unable to acquire the state change lock for the module: osgi.identity; type="osgi.bundle"; version:Version="4.6.1.201703071140-r"; osgi.identity="org.eclipse.egit.ui"; singleton:="true" [id=1025] STARTED [STARTED] - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:337) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:423) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.egit.ui.internal.ConfigurationChecker$1.run(ConfigurationChecker.java:45) - at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) -Caused by: java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - ... 13 more -Root exception: -java.util.concurrent.TimeoutException: Timeout after waiting 5 seconds to acquire the lock. - at org.eclipse.osgi.container.Module.lockStateChange(Module.java:334) - at org.eclipse.osgi.container.Module.start(Module.java:401) - at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:470) - at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) - at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:529) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:325) - at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:345) - at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:423) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372) - at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364) - at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161) - at java.lang.ClassLoader.loadClass(ClassLoader.java:357) - at org.eclipse.egit.ui.internal.ConfigurationChecker$1.run(ConfigurationChecker.java:45) - at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 13:23:48.986 +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.debug.ui 4 120 2017-10-10 22:58:39.018 +!MESSAGE Error logged from Debug UI: +!STACK 0 +org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) + at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) + at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.restoreLaunchHistory(LaunchConfigurationManager.java:501) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.loadLaunchHistories(LaunchConfigurationManager.java:1066) + at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager.getLaunchHistory(LaunchConfigurationManager.java:1038) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.internalGetHistory(AbstractLaunchHistoryAction.java:547) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.getToolTip(AbstractLaunchHistoryAction.java:233) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.updateTooltip(AbstractLaunchHistoryAction.java:198) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.initialize(AbstractLaunchHistoryAction.java:168) + at org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction.selectionChanged(AbstractLaunchHistoryAction.java:513) + at org.eclipse.ui.internal.PluginAction.refreshEnablement(PluginAction.java:206) + at org.eclipse.ui.internal.PluginAction.createDelegate(PluginAction.java:126) + at org.eclipse.ui.internal.WWinPluginAction.refreshActionList(WWinPluginAction.java:158) + at org.eclipse.ui.plugin.AbstractUIPlugin.lambda$0(AbstractUIPlugin.java:481) + at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:37) + at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) + at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4213) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3820) + at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) + at org.eclipse.jface.window.Window.open(Window.java:794) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) + at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:424) + at org.eclipse.jface.dialogs.MessageDialog.openInformation(MessageDialog.java:534) + at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:229) + at org.eclipse.ui.internal.WWinPluginAction.runWithEvent(WWinPluginAction.java:219) + at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:565) + at org.eclipse.jface.action.ActionContributionItem.lambda$5(ActionContributionItem.java:436) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4238) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3817) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) + +!ENTRY org.eclipse.wst.jsdt.ui 4 10001 2017-10-10 23:01:07.309 +!MESSAGE Internal Error +!STACK 1 +org.eclipse.wst.jsdt.internal.ui.JavaUIException: Problems reading information from XML 'OpenTypeHistory.xml' + at org.eclipse.wst.jsdt.internal.corext.util.History.createException(History.java:65) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:251) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:161) + at org.eclipse.wst.jsdt.internal.corext.util.OpenTypeHistory.(OpenTypeHistory.java:190) + at org.eclipse.wst.jsdt.internal.corext.util.OpenTypeHistory.getInstance(OpenTypeHistory.java:176) + at org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin.initializeAfterLoad(JavaScriptPlugin.java:357) + at org.eclipse.wst.jsdt.internal.ui.InitializeAfterLoadJob$RealJob.run(InitializeAfterLoadJob.java:33) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) +Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:249) + ... 6 more +!SUBENTRY 1 org.eclipse.wst.jsdt.ui 4 4 2017-10-10 23:01:07.309 +!MESSAGE Problems reading information from XML 'OpenTypeHistory.xml' +!STACK 0 +org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:249) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:161) + at org.eclipse.wst.jsdt.internal.corext.util.OpenTypeHistory.(OpenTypeHistory.java:190) + at org.eclipse.wst.jsdt.internal.corext.util.OpenTypeHistory.getInstance(OpenTypeHistory.java:176) + at org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin.initializeAfterLoad(JavaScriptPlugin.java:357) + at org.eclipse.wst.jsdt.internal.ui.InitializeAfterLoadJob$RealJob.run(InitializeAfterLoadJob.java:33) + at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) + +!ENTRY org.eclipse.wst.jsdt.ui 4 10001 2017-10-10 23:09:06.758 +!MESSAGE Internal Error +!STACK 1 +org.eclipse.wst.jsdt.internal.ui.JavaUIException: Problems reading information from XML 'QualifiedTypeNameHistory.xml' + at org.eclipse.wst.jsdt.internal.corext.util.History.createException(History.java:65) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:251) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:161) + at org.eclipse.wst.jsdt.internal.corext.util.QualifiedTypeNameHistory.(QualifiedTypeNameHistory.java:33) + at org.eclipse.wst.jsdt.internal.corext.util.QualifiedTypeNameHistory.getDefault(QualifiedTypeNameHistory.java:26) + at org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin.stop(JavaScriptPlugin.java:566) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) +Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:249) + ... 21 more +!SUBENTRY 1 org.eclipse.wst.jsdt.ui 4 4 2017-10-10 23:09:06.758 +!MESSAGE Problems reading information from XML 'QualifiedTypeNameHistory.xml' +!STACK 0 +org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 鍓嶈█涓笉鍏佽鏈夊唴瀹广 + at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) + at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:249) + at org.eclipse.wst.jsdt.internal.corext.util.History.load(History.java:161) + at org.eclipse.wst.jsdt.internal.corext.util.QualifiedTypeNameHistory.(QualifiedTypeNameHistory.java:33) + at org.eclipse.wst.jsdt.internal.corext.util.QualifiedTypeNameHistory.getDefault(QualifiedTypeNameHistory.java:26) + at org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin.stop(JavaScriptPlugin.java:566) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:835) + at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.EquinoxBundle.stopWorker0(EquinoxBundle.java:947) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.stopWorker(EquinoxBundle.java:314) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.decStartLevel(ModuleContainer.java:1669) + at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1588) + at org.eclipse.osgi.container.SystemModule.stopWorker(SystemModule.java:270) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker(EquinoxBundle.java:147) + at org.eclipse.osgi.container.Module.doStop(Module.java:636) + at org.eclipse.osgi.container.Module.stop(Module.java:498) + at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202) + at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165) + at java.lang.Thread.run(Unknown Source) +!SESSION 2017-10-10 23:09:49.817 ----------------------------------------------- +eclipse.buildId=4.7.1.M20170906-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2017-10-10 23:10:01.962 !MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-03 14:07:53.429 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 14:11:19.044 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-03 16:52:58.264 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 16:53:09.914 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-03 18:13:48.775 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 18:14:00.127 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-03 21:03:59.376 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 21:04:18.275 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-03 21:49:22.479 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 21:49:42.879 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-03 23:52:06.346 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-03 23:52:20.464 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-04 01:10:35.356 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-04 01:10:50.441 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.jface.text 2 0 2017-04-04 01:25:16.037 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-04 01:25:16.055 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' - -!ENTRY org.eclipse.e4.ui.workbench 4 0 2017-04-04 04:25:44.802 -!MESSAGE Error disposing widget for : org.eclipse.e4.ui.model.application.ui.menu.impl.MenuImpl null -!STACK 0 -java.lang.IllegalArgumentException: Argument not valid - at org.eclipse.swt.SWT.error(SWT.java:4514) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.SWT.error(SWT.java:4419) - at org.eclipse.swt.graphics.GC.setFont(GC.java:4617) - at org.eclipse.swt.custom.CTabFolderRenderer.computeSize(CTabFolderRenderer.java:340) - at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.computeSize(CTabRendering.java:200) - at org.eclipse.swt.custom.CTabFolder.setItemSize(CTabFolder.java:2819) - at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3764) - at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3697) - at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2090) - at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:340) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.sendResize(Control.java:3042) - at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1058) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1062) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) - at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) - at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) - at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) - at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) - at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) - at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) - at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1030) - at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:996) - at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1210) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1801) - at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) - at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1849) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) - at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1187) - at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) - at org.eclipse.swt.widgets.Widget.release(Widget.java:844) - at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:176) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:918) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:846) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$3.run(PartRenderingEngine.java:841) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:825) - at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:322) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Widget.release(Widget.java:836) - at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) - at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) - at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) - at org.eclipse.swt.widgets.Display.release(Display.java:3875) - at org.eclipse.swt.graphics.Device.dispose(Device.java:298) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.VtblCall(Native Method) - at org.eclipse.swt.widgets.TaskItem.setOverlayImage(TaskItem.java:296) - at org.eclipse.ui.internal.progress.TaskBarProgressManager.updateImage(TaskBarProgressManager.java:159) - at org.eclipse.ui.internal.progress.TaskBarProgressManager.access$4(TaskBarProgressManager.java:153) - at org.eclipse.ui.internal.progress.TaskBarProgressManager$2.runInUIThread(TaskBarProgressManager.java:117) - at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:97) - at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) - at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) - at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4211) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3827) - at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) - at org.eclipse.jface.window.Window.open(Window.java:794) - at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) - at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-04 04:25:44.955 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/widget/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl@1eb906f3 (elementId: org.eclipse.e4.ui.compatibility.editor, tags: [Editor, org.eclipse.jdt.ui.CompilationUnitEditor, removeOnHide], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer@2be89ba5, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (contributionURI: bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor, object: org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor@33ef701e, context: PartImpl (org.eclipse.e4.ui.compatibility.editor) Context, variables: [], label: ClientSession.java, iconURI: platform:/plugin/org.eclipse.jdt.ui/icons/full/obj16/jcu_obj.png, tooltip: null, dirty: false, closeable: true, description: null), Widget=null, org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl@1eb906f3 (elementId: org.eclipse.e4.ui.compatibility.editor, tags: [Editor, org.eclipse.jdt.ui.CompilationUnitEditor, removeOnHide], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer@2be89ba5, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (contributionURI: bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor, object: org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor@33ef701e, context: PartImpl (org.eclipse.e4.ui.compatibility.editor) Context, variables: [], label: ClientSession.java, iconURI: platform:/plugin/org.eclipse.jdt.ui/icons/full/obj16/jcu_obj.png, tooltip: null, dirty: false, closeable: true, description: null), AttName=widget, EventType=SET, OldValue=ContributedPartRenderer$2 {}, Widget=null}, AttName=widget, EventType=SET, OldValue=ContributedPartRenderer$2 {}} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@1ea3309a -!STACK 0 -java.lang.NullPointerException - at org.eclipse.ui.internal.NavigationHistory.getDisplay(NavigationHistory.java:176) - at org.eclipse.ui.internal.NavigationHistory.markEditor(NavigationHistory.java:193) - at org.eclipse.ui.internal.WorkbenchPage.updateActiveEditorSources(WorkbenchPage.java:411) - at org.eclipse.ui.internal.WorkbenchPage.firePartClosed(WorkbenchPage.java:5164) - at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart$1.handleEvent(CompatibilityPart.java:102) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Widget.release(Widget.java:836) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Composite.releaseChildren(Composite.java:952) - at org.eclipse.swt.widgets.Canvas.releaseChildren(Canvas.java:171) - at org.eclipse.swt.widgets.Decorations.releaseChildren(Decorations.java:807) - at org.eclipse.swt.widgets.Shell.releaseChildren(Shell.java:1368) - at org.eclipse.swt.widgets.Widget.release(Widget.java:839) - at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) - at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) - at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) - at org.eclipse.swt.widgets.Display.release(Display.java:3875) - at org.eclipse.swt.graphics.Device.dispose(Device.java:298) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.VtblCall(Native Method) - at org.eclipse.swt.widgets.TaskItem.setOverlayImage(TaskItem.java:296) - at org.eclipse.ui.internal.progress.TaskBarProgressManager.updateImage(TaskBarProgressManager.java:159) - at org.eclipse.ui.internal.progress.TaskBarProgressManager.access$4(TaskBarProgressManager.java:153) - at org.eclipse.ui.internal.progress.TaskBarProgressManager$2.runInUIThread(TaskBarProgressManager.java:117) - at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:97) - at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) - at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) - at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4211) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3827) - at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) - at org.eclipse.jface.window.Window.open(Window.java:794) - at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) - at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -!SESSION 2017-04-04 17:28:24.334 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.core.resources 2 10035 2017-04-04 17:28:32.785 -!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-04 17:28:41.471 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.jface.text 2 0 2017-04-04 17:32:45.473 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-04 17:32:45.475 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-04 17:35:12.546 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@4e4f979f (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@440e2406, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@4e4f979f (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@440e2406, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@165abf1 -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more - -!ENTRY org.eclipse.ui 4 0 2017-04-04 17:35:14.020 -!MESSAGE Unhandled event loop exception -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 47 more - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-04 17:35:49.040 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@507f7caa (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@440e2406, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@507f7caa (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@440e2406, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@165abf1 -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more - -!ENTRY org.eclipse.ui 4 0 2017-04-04 17:35:50.602 -!MESSAGE Unhandled event loop exception -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 47 more -!SESSION 2017-04-04 18:07:28.299 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-04 18:07:37.718 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-04 20:23:39.571 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-04 20:24:42.106 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.jface.text 2 0 2017-04-05 01:23:19.257 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-05 01:23:19.316 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-05 01:43:16.807 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-05 01:43:16.807 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' - -!ENTRY org.eclipse.e4.ui.workbench 4 0 2017-04-05 02:20:07.842 -!MESSAGE Error disposing widget for : org.eclipse.e4.ui.model.application.ui.menu.impl.MenuImpl null -!STACK 0 -java.lang.IllegalArgumentException: Argument not valid - at org.eclipse.swt.SWT.error(SWT.java:4514) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.SWT.error(SWT.java:4419) - at org.eclipse.swt.graphics.GC.setFont(GC.java:4617) - at org.eclipse.swt.custom.CTabFolderRenderer.computeSize(CTabFolderRenderer.java:340) - at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.computeSize(CTabRendering.java:200) - at org.eclipse.swt.custom.CTabFolder.setItemSize(CTabFolder.java:2819) - at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3764) - at org.eclipse.swt.custom.CTabFolder.updateItems(CTabFolder.java:3697) - at org.eclipse.swt.custom.CTabFolder.onResize(CTabFolder.java:2090) - at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:340) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.sendResize(Control.java:3042) - at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1058) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:1062) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1108) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) - at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) - at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) - at org.eclipse.swt.custom.StackLayout.layout(StackLayout.java:123) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) - at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3292) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3288) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.setRectangle(SashLayout.java:301) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:246) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.tileSubNodes(SashLayout.java:289) - at org.eclipse.e4.ui.workbench.renderers.swt.SashLayout.layout(SashLayout.java:163) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method) - at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3259) - at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1102) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3220) - at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3216) - at org.eclipse.swt.widgets.Control.setBounds(Control.java:3211) - at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204) - at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1386) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1797) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method) - at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1030) - at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:996) - at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1210) - at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1801) - at org.eclipse.swt.widgets.Canvas.WM_SIZE(Canvas.java:492) - at org.eclipse.swt.widgets.Decorations.WM_SIZE(Decorations.java:1849) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4874) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5699) - at org.eclipse.swt.widgets.Canvas.WM_WINDOWPOSCHANGED(Canvas.java:499) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4887) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.SetMenu(Native Method) - at org.eclipse.swt.widgets.Decorations.setMenuBar(Decorations.java:1187) - at org.eclipse.swt.widgets.Menu.releaseParent(Menu.java:1206) - at org.eclipse.swt.widgets.Widget.release(Widget.java:844) - at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(SWTPartRenderer.java:176) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(PartRenderingEngine.java:918) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$1(PartRenderingEngine.java:846) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$3.run(PartRenderingEngine.java:841) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(PartRenderingEngine.java:825) - at org.eclipse.ui.internal.WorkbenchWindow$1.handleEvent(WorkbenchWindow.java:322) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setWidget(UIElementImpl.java:261) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.unbindWidget(SWTPartRenderer.java:151) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer$1.widgetDisposed(SWTPartRenderer.java:139) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:124) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Widget.release(Widget.java:836) - at org.eclipse.swt.widgets.Widget.dispose(Widget.java:460) - at org.eclipse.swt.widgets.Decorations.dispose(Decorations.java:459) - at org.eclipse.swt.widgets.Shell.dispose(Shell.java:737) - at org.eclipse.swt.widgets.Display.release(Display.java:3875) - at org.eclipse.swt.graphics.Device.dispose(Device.java:298) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3358) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.VtblCall(Native Method) - at org.eclipse.swt.widgets.TaskItem.setOverlayImage(TaskItem.java:296) - at org.eclipse.ui.internal.progress.TaskBarProgressManager.updateImage(TaskBarProgressManager.java:159) - at org.eclipse.ui.internal.progress.TaskBarProgressManager.access$4(TaskBarProgressManager.java:153) - at org.eclipse.ui.internal.progress.TaskBarProgressManager$2.runInUIThread(TaskBarProgressManager.java:117) - at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:97) - at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) - at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182) - at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4211) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3827) - at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) - at org.eclipse.jface.window.Window.open(Window.java:794) - at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:396) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.open(MessageDialogWithToggle.java:115) - at org.eclipse.jface.dialogs.MessageDialogWithToggle.openOkCancelConfirm(MessageDialogWithToggle.java:210) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.promptOnExit(IDEWorkbenchWindowAdvisor.java:213) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$1.handleEvent(IDEWorkbenchAdvisor.java:165) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) - at org.eclipse.swt.widgets.Display.messageProc(Display.java:3371) - at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method) - at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547) - at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:506) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4897) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5123) - at org.eclipse.swt.internal.win32.OS.PeekMessageW(Native Method) - at org.eclipse.swt.internal.win32.OS.PeekMessage(OS.java:3144) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3819) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -!SESSION 2017-04-05 22:26:22.175 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.core.resources 2 10035 2017-04-05 22:26:29.318 -!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-05 22:26:36.687 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-06 00:47:18.247 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 00:47:50.832 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-06 02:03:23.389 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:03:44.687 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 02:04:07.770 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@78fdc1bb (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@75707f05, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@78fdc1bb (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@75707f05, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@6fffad6d -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more - -!ENTRY org.eclipse.ui 4 0 2017-04-06 02:04:10.005 -!MESSAGE Unhandled event loop exception -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 47 more -!SESSION 2017-04-06 02:08:17.558 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:08:38.242 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 02:08:41.170 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@3d45ea17 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@6971f5f4, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@3d45ea17 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@6971f5f4, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@562b791b -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more - -!ENTRY org.eclipse.ui 4 0 2017-04-06 02:08:44.687 -!MESSAGE Unhandled event loop exception -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 47 more - -!ENTRY org.eclipse.ui 4 0 2017-04-06 02:08:44.787 -!MESSAGE Unhandled event loop exception -!STACK 0 -java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 - at java.util.ArrayList.rangeCheck(ArrayList.java:653) - at java.util.ArrayList.get(ArrayList.java:429) - at org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.ConfigureBuildPathAction.run(ConfigureBuildPathAction.java:63) - at org.eclipse.jface.action.Action.runWithEvent(Action.java:473) - at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:565) - at org.eclipse.jface.action.ActionContributionItem.lambda$4(ActionContributionItem.java:397) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4236) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3824) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 02:08:49.521 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@6896ef29 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@6971f5f4, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@6896ef29 (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@6971f5f4, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@562b791b -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more -!SESSION 2017-04-06 02:21:00.143 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:21:23.640 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.jface.text 2 0 2017-04-06 02:28:12.434 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-06 02:28:12.437 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 02:31:03.685 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@3afbd1fd (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@10007fdc, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@3afbd1fd (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@10007fdc, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@5e31ad69 -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more - -!ENTRY org.eclipse.ui 4 0 2017-04-06 02:31:05.552 -!MESSAGE Unhandled event loop exception -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 47 more -!SESSION 2017-04-06 02:49:58.774 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:50:15.871 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-06 02:50:30.453 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-06 02:50:42.826 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. - -!ENTRY org.eclipse.jface.text 2 0 2017-04-06 03:01:55.359 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' - -!ENTRY org.eclipse.jface.text 2 0 2017-04-06 03:01:55.361 -!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' - -!ENTRY org.eclipse.equinox.event 4 0 2017-04-06 03:04:22.938 -!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/visible/SET] {ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@116c5bfa (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), org.eclipse.e4.data={ChangedElement=org.eclipse.e4.ui.model.application.ui.menu.impl.MenuSeparatorImpl@116c5bfa (elementId: additions, tags: [org.eclipse.jface.action.GroupMarker.GroupMarker(String)], contributorURI: null) (widget: null, renderer: org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer@2ff2a096, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: null, iconURI: null, tooltip: null, mnemonics: null), AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true}, AttName=visible, EventType=SET, OldValue=false, Widget=null, NewValue=true} to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@456839ee -!STACK 0 -org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) - at org.eclipse.swt.SWT.error(SWT.java:4533) - at org.eclipse.swt.SWT.error(SWT.java:4448) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) - at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) - at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) - at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:86) - at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:59) - at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) - at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) - at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1185) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.access$3(MenuManagerRenderer.java:1180) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer$3.handleEvent(MenuManagerRenderer.java:247) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40) - at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) - at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:145) - at org.eclipse.swt.widgets.Display.syncExec(Display.java:4821) - at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:211) - at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36) - at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) - at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) - at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) - at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) - at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) - at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) - at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) - at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:94) - at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) - at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) - at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:189) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:200) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:232) - at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:114) - at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) - at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) - at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) - at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) - at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) - at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) - at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) - at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) - at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5160) - at org.eclipse.swt.widgets.Control.windowProc(Control.java:4828) - at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) - at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1656) - at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) - at org.eclipse.swt.widgets.Display.windowProc(Display.java:5110) - at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) - at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) - at org.eclipse.swt.widgets.Display.runPopups(Display.java:4277) - at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3818) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:498) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) - at org.eclipse.equinox.launcher.Main.run(Main.java:1519) -Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) - at java.io.FileInputStream.open0(Native Method) - at java.io.FileInputStream.open(FileInputStream.java:195) - at java.io.FileInputStream.(FileInputStream.java:138) - at java.io.FileInputStream.(FileInputStream.java:93) - at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) - ... 75 more -!SESSION 2017-04-17 03:24:29.378 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-17 03:24:51.826 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-04-17 03:25:49.972 ----------------------------------------------- -eclipse.buildId=4.6.3.M20170301-0400 -java.version=1.8.0_121 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-04-17 03:25:58.567 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-08-28 00:39:00.693 ----------------------------------------------- -eclipse.buildId=4.7.0.I20170612-0950 -java.version=1.8.0_144 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:39:15.622 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-08-28 00:40:50.014 ----------------------------------------------- -eclipse.buildId=4.7.0.I20170612-0950 -java.version=1.8.0_144 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:41:00.718 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-08-28 00:42:12.549 ----------------------------------------------- -eclipse.buildId=4.7.0.I20170612-0950 -java.version=1.8.0_144 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:42:24.071 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-08-28 00:43:41.933 ----------------------------------------------- -eclipse.buildId=4.7.0.I20170612-0950 -java.version=1.8.0_144 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:43:52.374 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. -!SESSION 2017-08-28 00:49:21.174 ----------------------------------------------- -eclipse.buildId=4.7.0.I20170612-0950 -java.version=1.8.0_144 -java.vendor=Oracle Corporation -BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=zh_CN -Framework arguments: -product org.eclipse.epp.package.jee.product -Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product - -!ENTRY org.eclipse.egit.ui 2 0 2017-08-28 00:49:54.423 -!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git -user global configuration and to define the default location to store repositories: 'C:\Users\jinyu'. If this is -not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and -EGit might behave differently since they see different configuration options. -This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.jface.text 2 0 2017-10-11 01:21:16.159 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.number' + +!ENTRY org.eclipse.jface.text 2 0 2017-10-11 01:21:16.159 +!MESSAGE Duplicate template id: 'org.eclipse.wst.xslt.templates.xpath.round' + +!ENTRY org.eclipse.ui 4 0 2017-10-11 02:18:35.240 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-11 02:18:35.782 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-11 02:18:36.224 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more + +!ENTRY org.eclipse.ui 4 0 2017-10-11 02:19:34.779 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.e4.core.di.InjectionException: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler$1.run(UIEventObjectSupplier.java:64) + at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:233) + at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:144) + at org.eclipse.swt.widgets.Display.syncExec(Display.java:4889) + at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:212) + at org.eclipse.e4.ui.internal.di.UIEventObjectSupplier$UIEventHandler.handleEvent(UIEventObjectSupplier.java:61) + at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:201) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197) + at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1) + at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) + at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) + at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135) + at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78) + at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39) + at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:52) + at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:60) + at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374) + at org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setVisible(UIElementImpl.java:345) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord.updateVisibility(ContributionRecord.java:110) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:191) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:202) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.showMenu(MenuManagerShowProcessor.java:255) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerShowProcessor.menuAboutToHide(MenuManagerShowProcessor.java:112) + at org.eclipse.jface.internal.MenuManagerEventHelper.showEventPostHelper(MenuManagerEventHelper.java:92) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:471) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:669) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.scheduleManagerUpdate(MenuManagerRenderer.java:1214) + at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.subscribeUIElementTopicAllRenderedVisibility(MenuManagerRenderer.java:200) + at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55) + ... 64 more +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 78 more + +!ENTRY org.eclipse.ui 4 0 2017-10-11 02:19:34.871 +!MESSAGE Unhandled event loop exception +!STACK 0 +org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆)) + at org.eclipse.swt.SWT.error(SWT.java:4533) + at org.eclipse.swt.SWT.error(SWT.java:4448) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:175) + at org.eclipse.tm.terminal.view.ui.local.showin.ExternalExecutablesManager.loadImage(ExternalExecutablesManager.java:264) + at org.eclipse.tm.terminal.view.ui.local.showin.DynamicContributionItems.getContributionItems(DynamicContributionItems.java:77) + at org.eclipse.ui.actions.CompoundContributionItem.getContributionItemsToFill(CompoundContributionItem.java:80) + at org.eclipse.ui.actions.CompoundContributionItem.fill(CompoundContributionItem.java:54) + at org.eclipse.ui.internal.menus.DynamicMenuContributionItem.fill(DynamicMenuContributionItem.java:147) + at org.eclipse.jface.action.MenuManager.doItemFill(MenuManager.java:728) + at org.eclipse.jface.action.MenuManager.update(MenuManager.java:810) + at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:472) + at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465) + at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:497) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:256) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:5204) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4872) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:359) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1657) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2199) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5178) + at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) + at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:262) + at org.eclipse.swt.widgets.Display.runPopups(Display.java:4279) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3811) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) + at org.eclipse.equinox.launcher.Main.run(Main.java:1499) +Caused by: java.io.FileNotFoundException: d:\Program Files\Git\mingw64\share\git\git-for-windows.ico (绯荤粺鎵句笉鍒版寚瀹氱殑璺緞銆) + at java.io.FileInputStream.open0(Native Method) + at java.io.FileInputStream.open(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at java.io.FileInputStream.(Unknown Source) + at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:172) + ... 47 more diff --git a/.metadata/.mylyn/.tasks.xml.zip b/.metadata/.mylyn/.tasks.xml.zip index c66159bf958bab91969322c14d4318d39b57f7ba..ed2df7d91ccdcda80f0fe22e31cfde7d26504cfe 100644 GIT binary patch delta 26 gcmaFO_?nR?z?+#xgn@&DgF#tfBF}6lAi2^B08Zis&j0`b delta 26 gcmaFO_?nR?z?+#xgn@&DgF&2kBF}6lAi2^B08RJ>u>b%7 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/0/209a8eaa21ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/0/209a8eaa21ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7b15fab --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/0/209a8eaa21ac001710ff8a7c6bda0fb8 @@ -0,0 +1,290 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/0/c0b151e22dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/0/c0b151e22dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..3daf557 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/0/c0b151e22dac001710ff8a7c6bda0fb8 @@ -0,0 +1,99 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1/e085ced59aad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/1/e085ced59aad0017181ed9113883eda9 new file mode 100644 index 0000000..4cb59bf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1/e085ced59aad0017181ed9113883eda9 @@ -0,0 +1,502 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) +// { +// //比当前发送包都大,修正 cd +// lastAckSequenceNumber=ackNumber; +// } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1/f0f3e82c6fa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/1/f0f3e82c6fa800171a8482560d609ceb new file mode 100644 index 0000000..a5ca7b7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1/f0f3e82c6fa800171a8482560d609ceb @@ -0,0 +1,104 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +// private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + int num=0; + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + log.info("发送数据:"+); + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/10/709e69df58ac00171c63d91e40f02a62 b/.metadata/.plugins/org.eclipse.core.resources/.history/10/709e69df58ac00171c63d91e40f02a62 new file mode 100644 index 0000000..d76732b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/10/709e69df58ac00171c63d91e40f02a62 @@ -0,0 +1,152 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/10/d0aa129d98ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/10/d0aa129d98ad0017181ed9113883eda9 new file mode 100644 index 0000000..f809a3a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/10/d0aa129d98ad0017181ed9113883eda9 @@ -0,0 +1,36 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //192.168.30.128 + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("192.168.30.128", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/10/f0565a8d18ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/10/f0565a8d18ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..2452ee7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/10/f0565a8d18ac001710ff8a7c6bda0fb8 @@ -0,0 +1,12 @@ +/** + * + */ +package judp; + +/** + * @author jinyu + * + */ +public class PackagetSub { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/12/90ddb49ea2ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/12/90ddb49ea2ad0017181ed9113883eda9 new file mode 100644 index 0000000..0df1509 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/12/90ddb49ea2ad0017181ed9113883eda9 @@ -0,0 +1,103 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; +import java.net.URL; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * @author jinyu + * + */ +public class ReadXml { + public static String getPath() { + URL url = ReadXml.class.getProtectionDomain().getCodeSource().getLocation(); + String filePath = null; + try { + filePath = URLDecoder.decode(url.getPath(), "utf-8");// 转化为utf-8编码 + } catch (Exception e) { + e.printStackTrace(); + } + if (filePath.endsWith(".jar")) {// 可执行jar包运行的结果里包含".jar" + // 截取路径中的jar包名 + filePath = filePath.substring(0, filePath.lastIndexOf("/") + 1); + } + + File file = new File(filePath); + + // /If this abstract pathname is already absolute, then the pathname + // string is simply returned as if by the getPath method. If this + // abstract pathname is the empty abstract pathname then the pathname + // string of the current user directory, which is named by the system + // property user.dir, is returned. + filePath = file.getAbsolutePath();//得到windows下的正确路径 + return filePath; + } +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Document doc = null; + try { + doc = (Document) builder.parse(is); + } catch (SAXException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + NodeList list=doc.getElementsByTagName("IP"); + String ip= list.item(0).getTextContent(); + list=doc.getElementsByTagName("Port"); + String port=list.item(0).getTextContent(); + list=doc.getElementsByTagName("Dir"); + String dir=list.item(0).getTextContent(); + String strxml=ip+","+port+","+dir; + return strxml; + } +private String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/12/e051f64398ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/12/e051f64398ad0017181ed9113883eda9 new file mode 100644 index 0000000..377ac17 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/12/e051f64398ad0017181ed9113883eda9 @@ -0,0 +1,43 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + SendFiles send=new SendFiles("192.168.30.128", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/13/10bc98feb5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/13/10bc98feb5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..eba3680 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/13/10bc98feb5ac001716b9ca6d5abb90bc @@ -0,0 +1,192 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.KeepAlive; +import udt.packets.Shutdown; + +/** + * server side session in client-server mode + */ +public class ServerSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ServerSession.class.getName()); + + private final UDPEndPoint endPoint; + + //last received packet (for testing purposes) + private UDTPacket lastPacket; + + + public ServerSession(DatagramPacket dp, UDPEndPoint endPoint)throws SocketException,UnknownHostException{ + super("ServerSession localPort="+endPoint.getLocalPort()+" peer="+dp.getAddress()+":"+dp.getPort(),new Destination(dp.getAddress(),dp.getPort())); + this.endPoint=endPoint; + logger.info("Created "+toString()+" talking to "+dp.getAddress()+":"+dp.getPort()); + } + + int n_handshake=0; + + @Override + public void received(UDTPacket packet, Destination peer){ + lastPacket=packet; + + if(packet instanceof ConnectionHandshake) { + ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; + logger.info("Received "+connectionHandshake); + + if (getState()<=ready){ + destination.setSocketID(connectionHandshake.getSocketID()); + + if(getState()<=handshaking){ + setState(handshaking); + } + try{ + handleHandShake(connectionHandshake); + n_handshake++; + try{ + setState(ready); + socket=new UDTSocket(endPoint, this); + cc.init(); + }catch(Exception uhe){ + //session is invalid + logger.log(Level.SEVERE,"",uhe); + setState(invalid); + } + }catch(IOException ex){ + //session invalid + logger.log(Level.WARNING,"Error processing ConnectionHandshake",ex); + setState(invalid); + } + return; + } + + }else if(packet instanceof KeepAlive) { + socket.getReceiver().resetEXPTimer(); + active = true; + return; + } + + if(getState()== ready) { + active = true; + + if (packet instanceof KeepAlive) { + //nothing to do here + return; + }else if (packet instanceof Shutdown) { + try{ + socket.getReceiver().stop(); + }catch(IOException ex){ + logger.log(Level.WARNING,"",ex); + } + setState(shutdown); + System.out.println("SHUTDOWN ***"); + active = false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + + else{ + try{ + long seqNo=packet.getPacketSequenceNumber(); + logger.info("DataPacket:"+seqNo); + if(packet.forSender()){ + socket.getSender().receive(packet); + }else{ + socket.getReceiver().receive(packet); + } + }catch(Exception ex){ + //session invalid + logger.log(Level.SEVERE,"",ex); + setState(invalid); + } + } + return; + + } + + + } + + /** + * for testing use only + */ + UDTPacket getLastPacket(){ + return lastPacket; + } + + /** + * handle the connection handshake:
+ *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/13/e0517759cbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/13/e0517759cbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..3a6e18d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/13/e0517759cbac001716b9ca6d5abb90bc @@ -0,0 +1,194 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + //this.position=new HashSet(size); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + /** + * 清除重复检验 + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/14/0005620c24ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/14/0005620c24ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..4afc100 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/14/0005620c24ac001710ff8a7c6bda0fb8 @@ -0,0 +1,328 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用read[] + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=PackagetSub.split(data); + for(int i=0;i position; + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.position=new HashSet(size); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + /** + * 清除重复检验 + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/14/c081423d1cac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/14/c081423d1cac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..e7800ce --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/14/c081423d1cac001710ff8a7c6bda0fb8 @@ -0,0 +1,32 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] data; +public long id; +public DataStruct(int num) +{ + data=new byte[num][]; +} +public boolean addData(byte[]data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + int index=buf.getInt(); + dataLen=buf.getInt(); + byte[] tmp=new byte[buf.limit()-buf.position()]; + buf.get(tmp); + data[index]=tmp; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/15/503d09ac4fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/15/503d09ac4fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..93433e1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/15/503d09ac4fac001710ff8a7c6bda0fb8 @@ -0,0 +1,246 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + public SocketReference(judpSocket socket, long socketID2, ReferenceQueue q) { + + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/16/109c5e88d6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/16/109c5e88d6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..952c0ed --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/16/109c5e88d6ac001716b9ca6d5abb90bc @@ -0,0 +1,288 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取;也要外部快速读取 + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + // cd + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + + if(readPosition==size) + {readPosition=0; + if(this.islagerRead) + { + //cd + clearDeHash(this.size-leftNum); + } + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } + + /** + * 设置大数据 + * @param islarge + */ + public void setlargeRead(boolean islarge) + { + this.islagerRead=islarge; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/16/406135d6daac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/16/406135d6daac001716b9ca6d5abb90bc new file mode 100644 index 0000000..ab96466 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/16/406135d6daac001716b9ca6d5abb90bc @@ -0,0 +1,284 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + System.out.println("sendBlocking start"); + client.sendBlocking(data); + r=data.length; + sumLen+=r; + System.out.println("sendBlocking end"); + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/17/30f8db4bd8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/17/30f8db4bd8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..b510793 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/17/30f8db4bd8ac001716b9ca6d5abb90bc @@ -0,0 +1,338 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/timespan/1000; + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/17/80cd43731aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/17/80cd43731aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..4f568b8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/17/80cd43731aac001710ff8a7c6bda0fb8 @@ -0,0 +1,73 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s0) + { + if(lastAckSequenceNumber/10000!=ackNumber/10000) + { + //修正 + //ackNumber 特别大,则会全部删除,特别小,一个都不会删除 + if(lastAckSequenceNumberthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + } + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/18/006c2690d8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/18/006c2690d8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..f45ab0f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/18/006c2690d8ac001716b9ca6d5abb90bc @@ -0,0 +1,368 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + // TODO Auto-generated method stub + + } + + }) + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/18/6065932703ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/18/6065932703ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..04c314e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/18/6065932703ac001710ff8a7c6bda0fb8 @@ -0,0 +1,16 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/18/c05c601f6da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/18/c05c601f6da800171a8482560d609ceb new file mode 100644 index 0000000..9361825 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/18/c05c601f6da800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * 文件名:TestRecFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpRecviceFile; + +/** + * + * 项目名称:judp + * 类名称:TestRecFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:42 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:42 + * 修改备注: + * @version + * + */ +public class TestRecFiles { + + public static void main(String[] args) { + judpRecviceFile rec=new judpRecviceFile("127.0.0.1", 5555, "E:\\Study\\java\\filesudt\\send\\12.rmvb", "E:\\Study\\java\\filesudt\\rec\\1.rmvb"); + rec.start(); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/18/f0e7afc269a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/18/f0e7afc269a800171a8482560d609ceb new file mode 100644 index 0000000..6c21308 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/18/f0e7afc269a800171a8482560d609ceb @@ -0,0 +1,114 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ +try { + UDTSocket socket=SocketControls.getInstance().getSocket(); + judpSocket jsocket= sessionHandoff.take(); + return jsocket; +} catch (InterruptedException e) { + logger.info("judpSocket接收中断:"+e.getMessage()); + e.printStackTrace(); +} +return null; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/19/00d683551aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/19/00d683551aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..a08d983 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/19/00d683551aac001710ff8a7c6bda0fb8 @@ -0,0 +1,77 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + byte[][] result=new byte[num][]; + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖 + buffer[insert]=data; + } + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/19/60d4a2c04fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/19/60d4a2c04fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..95cee2d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/19/60d4a2c04fac001710ff8a7c6bda0fb8 @@ -0,0 +1,139 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i hash=new ConcurrentHashMap(); + private ConcurrentLinkedQueue queue=new ConcurrentLinkedQueue(); +public boolean addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + boolean r= struct.addData(data); + if(r) + { + byte[]result =struct.getData(); + byte[] tmp=new byte[result.length]; + System.arraycopy(result, 0, tmp, 0, tmp.length); + queue.offer(tmp); + struct.clear(); + } + return r; + +} +public byte[] getData() +{ + return queue.poll(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1a/f0fb59a4a1ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/1a/f0fb59a4a1ad0017181ed9113883eda9 new file mode 100644 index 0000000..cea913a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1a/f0fb59a4a1ad0017181ed9113883eda9 @@ -0,0 +1,50 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + ReadXml rd=new ReadXml(); + String xml= rd.readXml("config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + SendFiles send=new SendFiles(config[0], Integer.valueOf(config[1])); + FilesWatch watch=new FilesWatch(); + String dir=config[2]; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1b/201f78bc6da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/1b/201f78bc6da800171a8482560d609ceb new file mode 100644 index 0000000..9842219 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1b/201f78bc6da800171a8482560d609ceb @@ -0,0 +1,56 @@ +/** + * 文件名:TestSendFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpSendFile; + +/** + * + * 项目名称:judp + * 类名称:TestSendFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:25 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:25 + * 修改备注: + * @version + * + */ +public class TestSendFile { + + /** + + * TODO(这里描述这个方法适用条件 – 可选) + + * @param name + + * @return + + * + + + */ + public static void main(String[] args) { + judpSendFile jsend=new judpSendFile("192.168.10.86",5555); + jsend.startSend(); + + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1c/404d73a415ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/404d73a415ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..65a5a4a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/404d73a415ac001710ff8a7c6bda0fb8 @@ -0,0 +1,35 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("127.0.0.1", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1c/509f6ba4c9ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/509f6ba4c9ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..922b432 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/509f6ba4c9ac001716b9ca6d5abb90bc @@ -0,0 +1,193 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.KeepAlive; +import udt.packets.Shutdown; + +/** + * server side session in client-server mode + */ +public class ServerSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ServerSession.class.getName()); + + private final UDPEndPoint endPoint; + + //last received packet (for testing purposes) + private UDTPacket lastPacket; + + + public ServerSession(DatagramPacket dp, UDPEndPoint endPoint)throws SocketException,UnknownHostException{ + super("ServerSession localPort="+endPoint.getLocalPort()+" peer="+dp.getAddress()+":"+dp.getPort(),new Destination(dp.getAddress(),dp.getPort())); + this.endPoint=endPoint; + logger.info("Created "+toString()+" talking to "+dp.getAddress()+":"+dp.getPort()); + } + + int n_handshake=0; + + @Override + public void received(UDTPacket packet, Destination peer){ + lastPacket=packet; + + if(packet instanceof ConnectionHandshake) { + ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; + logger.info("Received "+connectionHandshake); + + if (getState()<=ready){ + destination.setSocketID(connectionHandshake.getSocketID()); + + if(getState()<=handshaking){ + setState(handshaking); + } + try{ + handleHandShake(connectionHandshake); + n_handshake++; + try{ + setState(ready); + socket=new UDTSocket(endPoint, this); + cc.init(); + }catch(Exception uhe){ + //session is invalid + logger.log(Level.SEVERE,"",uhe); + setState(invalid); + } + }catch(IOException ex){ + //session invalid + logger.log(Level.WARNING,"Error processing ConnectionHandshake",ex); + setState(invalid); + } + return; + } + + }else if(packet instanceof KeepAlive) { + socket.getReceiver().resetEXPTimer(); + active = true; + return; + } + + if(getState()== ready) { + active = true; + + if (packet instanceof KeepAlive) { + //nothing to do here + return; + }else if (packet instanceof Shutdown) { + try{ + socket.getReceiver().stop(); + }catch(IOException ex){ + logger.log(Level.WARNING,"",ex); + } + setState(shutdown); + System.out.println("SHUTDOWN ***"); + active = false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + + else{ + try{ + long seqNo=packet.getPacketSequenceNumber(); + if(seqNo!=-1) + logger.info("DataPacket session:"+seqNo); + if(packet.forSender()){ + socket.getSender().receive(packet); + }else{ + socket.getReceiver().receive(packet); + } + }catch(Exception ex){ + //session invalid + logger.log(Level.SEVERE,"",ex); + setState(invalid); + } + } + return; + + } + + + } + + /** + * for testing use only + */ + UDTPacket getLastPacket(){ + return lastPacket; + } + + /** + * handle the connection handshake:
+ *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1d/d09bb2d219ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/1d/d09bb2d219ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..aab63e6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1d/d09bb2d219ac001710ff8a7c6bda0fb8 @@ -0,0 +1,74 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + byte[][] data=new byte[num][]; + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(writeFile(tmp)) + { + ss.close(); + break; + } + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1e/6080d540c8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/6080d540c8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..86114b4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/6080d540c8ac001716b9ca6d5abb90bc @@ -0,0 +1,195 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + //private final HashSet position; + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.position=new HashSet(size); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + /** + * 清除重复检验 + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1e/c080de4460ac00171ca19969f19d2325 b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/c080de4460ac00171ca19969f19d2325 new file mode 100644 index 0000000..be396f8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/c080de4460ac00171ca19969f19d2325 @@ -0,0 +1,238 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.concurrent.TimeUnit; + +import udt.packets.DataPacket; + +/** + * UDTSocket is analogous to a normal java.net.Socket, it provides input and + * output streams for the application + * + * TODO is it possible to actually extend java.net.Socket ? + * + * + */ +public class UDTSocket { + //一个session对应一个udtsocket + //endpoint + private final UDPEndPoint endpoint; + + private volatile boolean active; + + private volatile boolean close=false;//关闭标识,cd + + //processing received data + private UDTReceiver receiver; + private UDTSender sender; + + private final UDTSession session; + + private UDTInputStream inputStream; + private UDTOutputStream outputStream; + + /** + * @param host + * @param port + * @param endpoint + * @throws SocketException,UnknownHostException + */ + public UDTSocket(UDPEndPoint endpoint, UDTSession session)throws SocketException,UnknownHostException{ + this.endpoint=endpoint; + this.session=session; + this.receiver=new UDTReceiver(session,endpoint); + this.sender=new UDTSender(session,endpoint); + } + + public UDTReceiver getReceiver() { + return receiver; + } + + public void setReceiver(UDTReceiver receiver) { + this.receiver = receiver; + } + + public UDTSender getSender() { + return sender; + } + + public void setSender(UDTSender sender) { + this.sender = sender; + } + + public void setActive(boolean active) { + this.active = active; + } + + public boolean isActive() { + return active; + } + + public UDPEndPoint getEndpoint() { + return endpoint; + } + + public boolean isClose() + { + return close; + } + /** + * get the input stream for reading from this socket + * @return + */ + public synchronized UDTInputStream getInputStream()throws IOException{ + if(inputStream==null){ + inputStream=new UDTInputStream(this); + } + return inputStream; + } + + /** + * get the output stream for writing to this socket + * @return + */ + public synchronized UDTOutputStream getOutputStream(){ + if(outputStream==null){ + outputStream=new UDTOutputStream(this); + } + return outputStream; + } + + public final UDTSession getSession(){ + return session; + } + + /** + * write single block of data without waiting for any acknowledgement + * @param data + */ + protected void doWrite(byte[]data)throws IOException{ + doWrite(data, 0, data.length); + + } + + /** + * write the given data + * @param data - the data array + * @param offset - the offset into the array + * @param length - the number of bytes to write + * @throws IOException + */ + protected void doWrite(byte[]data, int offset, int length)throws IOException{ + try{ + doWrite(data, offset, length, Integer.MAX_VALUE, TimeUnit.MILLISECONDS); + }catch(InterruptedException ie){ + IOException io=new IOException(); + io.initCause(ie); + throw io; + } + } + + /** + * write the given data, waiting at most for the specified time if the queue is full + * @param data + * @param offset + * @param length + * @param timeout + * @param units + * @throws IOException - if data cannot be sent + * @throws InterruptedException + */ + protected void doWrite(byte[]data, int offset, int length, int timeout, TimeUnit units)throws IOException,InterruptedException{ + int chunksize=session.getDatagramSize()-24;//need some bytes for the header + ByteBuffer bb=ByteBuffer.wrap(data,offset,length); + long seqNo=0; + while(bb.remaining()>0){ + int len=Math.min(bb.remaining(),chunksize); + byte[]chunk=new byte[len]; + bb.get(chunk); + DataPacket packet=new DataPacket(); + seqNo=sender.getNextSequenceNumber(); + packet.setPacketSequenceNumber(seqNo); + packet.setSession(session); + packet.setDestinationID(session.getDestination().getSocketID()); + packet.setData(chunk); + System.out.println("sender sendUdtPacket1"); + //put the packet into the send queue + if(!sender.sendUdtPacket(packet, timeout, units)){ + throw new IOException("Queue full"); + } + System.out.println("sender sendUdtPacket2"); + } + if(length>0)active=true; + System.out.println("sender sendUdtPacket out"); + } + /** + * will block until the outstanding packets have really been sent out + * and acknowledged + */ + protected void flush() throws InterruptedException{ + if(!active)return; + final long seqNo=sender.getCurrentSequenceNumber(); + if(seqNo<0)throw new IllegalStateException(); + while(!sender.isSentOut(seqNo)){ + Thread.sleep(5); + } + if(seqNo>-1){ + //wait until data has been sent out and acknowledged + while(active && !sender.haveAcknowledgementFor(seqNo)){ + sender.waitForAck(seqNo); + } + } + //TODO need to check if we can pause the sender... + //sender.pause(); + } + + //writes and wait for ack + protected void doWriteBlocking(byte[]data)throws IOException, InterruptedException{ + doWrite(data); + System.out.println("flush"); + flush(); + } + + /** + * close the connection + * @throws IOException + */ + public void close()throws IOException{ + if(inputStream!=null)inputStream.close(); + if(outputStream!=null)outputStream.close(); + active=false; + close=true; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1e/e06c053c27ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/e06c053c27ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..b853b8c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/e06c053c27ac001710ff8a7c6bda0fb8 @@ -0,0 +1,328 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=PackagetSub.splitData(data); + for(int i=0;i hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + /** + * 接收数据写入文件 + */ + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + else + { + recData(); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1f/c0c69f405ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/1f/c0c69f405ca800171a8482560d609ceb new file mode 100644 index 0000000..c61f259 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1f/c0c69f405ca800171a8482560d609ceb @@ -0,0 +1,211 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + TimeUnit.MILLISECONDS.sleep(100); + } + } + + } + + }); + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1f/e004bd9ee7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/1f/e004bd9ee7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..f809a3a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1f/e004bd9ee7ac001716b9ca6d5abb90bc @@ -0,0 +1,36 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //192.168.30.128 + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("192.168.30.128", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2/b0e3a7446ba800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/2/b0e3a7446ba800171a8482560d609ceb new file mode 100644 index 0000000..5276bfb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2/b0e3a7446ba800171a8482560d609ceb @@ -0,0 +1,112 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/20/4057838a1aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/20/4057838a1aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/20/602e70256da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/20/602e70256da800171a8482560d609ceb new file mode 100644 index 0000000..6d9a951 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/20/602e70256da800171a8482560d609ceb @@ -0,0 +1,56 @@ +/** + * 文件名:TestSendFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpSendFile; + +/** + * + * 项目名称:judp + * 类名称:TestSendFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:25 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:25 + * 修改备注: + * @version + * + */ +public class TestSendFiles { + + /** + + * TODO(这里描述这个方法适用条件 – 可选) + + * @param name + + * @return + + * + + + */ + public static void main(String[] args) { + judpSendFile jsend=new judpSendFile("192.168.10.86",5555); + jsend.startSend(); + + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/20/c06bb2f50eac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/20/c06bb2f50eac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..5de1ac4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/20/c06bb2f50eac001710ff8a7c6bda0fb8 @@ -0,0 +1,101 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.util.HashMap; +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + @SuppressWarnings("rawtypes") + private final ReferenceQueue q = new ReferenceQueue(); + private volatile long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private final HashMap,Long> map=new HashMap,Long> (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + map.remove(k); + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + map.put(tmp, socket.getSocketID()); + if(num%10==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/21/10bf9d62dbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/21/10bf9d62dbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..767dffd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/21/10bf9d62dbac001716b9ca6d5abb90bc @@ -0,0 +1,368 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + // readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/21/f0f57f2ec5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/21/f0f57f2ec5ad0017181ed9113883eda9 new file mode 100644 index 0000000..dda5990 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/21/f0f57f2ec5ad0017181ed9113883eda9 @@ -0,0 +1,520 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/22/3024d0d16da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/22/3024d0d16da800171a8482560d609ceb new file mode 100644 index 0000000..c3f6f9b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/22/3024d0d16da800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(Test.TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + SendFiles send=new SendFiles("127.0.0.1", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/22/40a8ff391bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/22/40a8ff391bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..29298ec --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/22/40a8ff391bac001710ff8a7c6bda0fb8 @@ -0,0 +1,15 @@ +/** + * + */ +package judp; + +/** + * @author jinyu + * + */ +public class PackagetCombin { +public static void addData(byte[] data) +{ + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/22/70ca7fc634ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/22/70ca7fc634ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..5bb2e1a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/22/70ca7fc634ac001710ff8a7c6bda0fb8 @@ -0,0 +1,333 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i hashMap=new WeakHashMap (); + private final HashMap,Long> map=new HashMap,Long> (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + map.remove(k); + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + + /** + * 单例 + * @param point + * @return + */ + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + + /** + * 添加judpSocket + * @param socket + */ + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + map.put(tmp, socket.getSocketID()); + if(num%10==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/23/00e997b8a2ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/23/00e997b8a2ad0017181ed9113883eda9 new file mode 100644 index 0000000..0f32eca --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/23/00e997b8a2ad0017181ed9113883eda9 @@ -0,0 +1,55 @@ +/** + * + */ +package net.File; + +import java.io.File; +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + String path = TestSendFiles.class.getProtectionDomain().getCodeSource().getLocation().getFile(); + int firstIndex = path.lastIndexOf(System.getProperty("path.separator")) + 1; + int lastIndex = path.lastIndexOf(File.separator) + 1; + path = path.substring(firstIndex, lastIndex); + ReadXml rd=new ReadXml(); + String xml= rd.readXml(path+"/config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + SendFiles send=new SendFiles(config[0], Integer.valueOf(config[1])); + FilesWatch watch=new FilesWatch(); + String dir=config[2]; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/23/301509806da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/23/301509806da800171a8482560d609ceb new file mode 100644 index 0000000..1c2c391 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/23/301509806da800171a8482560d609ceb @@ -0,0 +1,35 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFile { + private static Logger log=Logger.getLogger(TestRecFile.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("127.0.0.1", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/23/a089455d57ac00171c63d91e40f02a62 b/.metadata/.plugins/org.eclipse.core.resources/.history/23/a089455d57ac00171c63d91e40f02a62 new file mode 100644 index 0000000..9bab3f7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/23/a089455d57ac00171c63d91e40f02a62 @@ -0,0 +1,152 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/23/d00f297c26ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/23/d00f297c26ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..b73e40b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/23/d00f297c26ac001710ff8a7c6bda0fb8 @@ -0,0 +1,87 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (SocketReference) q.remove()) != null) { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/24/70abceb2e0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/24/70abceb2e0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..a3319cf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/24/70abceb2e0ac001716b9ca6d5abb90bc @@ -0,0 +1,151 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + + } + long endTime=System.currentTimeMillis(); + client.close(); + dis.close(); + long speed=fLen/((endTime-startTime)/1000); + log.info("发送完成:"+f.getName()+",平均速度:"+speed/1024/1024); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/24/d09c215ae5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/24/d09c215ae5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..3ca6cea --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/24/d09c215ae5ac001716b9ca6d5abb90bc @@ -0,0 +1,247 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + /** + * 接收数据写入文件 + */ + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + //空文件不会有数据 + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + else + { + recData(); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/25/c0e0b2fbe2ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/25/c0e0b2fbe2ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..2a96245 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/25/c0e0b2fbe2ac001716b9ca6d5abb90bc @@ -0,0 +1,199 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/26/204e38905bac00171c63d91e40f02a62 b/.metadata/.plugins/org.eclipse.core.resources/.history/26/204e38905bac00171c63d91e40f02a62 new file mode 100644 index 0000000..55ea144 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/26/204e38905bac00171c63d91e40f02a62 @@ -0,0 +1,246 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/27/6089d24d1aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/27/6089d24d1aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c78e323 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/27/6089d24d1aac001710ff8a7c6bda0fb8 @@ -0,0 +1,77 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + byte[][] result=new byte[num][]; + for(int i=0;i=buffer.length) + { + //检查成功 + if(sumLen==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/27/f03094536aa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/27/f03094536aa800171a8482560d609ceb new file mode 100644 index 0000000..c577d9f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/27/f03094536aa800171a8482560d609ceb @@ -0,0 +1,16 @@ +/** + * + */ +package net.File; + + +import java.nio.file.WatchEvent.Kind; + +/** + * @author jinyu + * + */ +public class FileMonitor { +public String file; +public Kind kind; +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/28/20611a6ec3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/28/20611a6ec3ad0017181ed9113883eda9 new file mode 100644 index 0000000..7d3ddd7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/28/20611a6ec3ad0017181ed9113883eda9 @@ -0,0 +1,492 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/28/b08c10a81fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/28/b08c10a81fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..156b628 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/28/b08c10a81fac001710ff8a7c6bda0fb8 @@ -0,0 +1,38 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); + private ConcurrentLinkedQueue queue=new ConcurrentLinkedQueue(); +public boolean addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + boolean r= struct.addData(data); + if(r) + { + byte[]result =struct.getData(); + byte[] tmp=new byte[result.length]; + System.arraycopy(result, 0, tmp, 0, tmp.length); + queue.offer(struct.getData()); + } + return r; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/29/306a36aed6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/29/306a36aed6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..8d74cec --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/29/306a36aed6ac001716b9ca6d5abb90bc @@ -0,0 +1,289 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取;也要外部快速读取 + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + // cd + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + + if(readPosition==size) + {readPosition=0; + if(this.islagerRead) + { + //cd + clearDeHash(this.size-leftNum); + } + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } + + /** + * 设置大数据读取 + * 默认 false + * @param islarge + */ + public void setLargeRead(boolean islarge) + { + this.islagerRead=islarge; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2a/507d3e2903ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/2a/507d3e2903ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f2b2a40 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2a/507d3e2903ac001710ff8a7c6bda0fb8 @@ -0,0 +1,21 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + + public SocketReference(T referent) { + super(referent); + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2a/b06d26c4cfac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/2a/b06d26c4cfac001716b9ca6d5abb90bc new file mode 100644 index 0000000..354bd7b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2a/b06d26c4cfac001716b9ca6d5abb90bc @@ -0,0 +1,233 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + if(highestReadSequenceNumber+1 hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + hasSocket.put(socket); + } + } + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2b/b0ae6971bcac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/2b/b0ae6971bcac001716b9ca6d5abb90bc new file mode 100644 index 0000000..c65c632 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2b/b0ae6971bcac001716b9ca6d5abb90bc @@ -0,0 +1,604 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ControlPacket; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.packets.Shutdown; +import udt.packets.ControlPacket.ControlPacketType; +import udt.receiver.AckHistoryEntry; +import udt.receiver.AckHistoryWindow; +import udt.receiver.PacketHistoryWindow; +import udt.receiver.PacketPairWindow; +import udt.receiver.ReceiverLossList; +import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + +/** + * receiver part of a UDT entity + * @see UDTSender + */ +public class UDTReceiver { + + private static final Logger logger=Logger.getLogger(UDTReceiver.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //record seqNo of detected lostdata and latest feedback time + private final ReceiverLossList receiverLossList; + + //record each sent ACK and the sent time + private final AckHistoryWindow ackHistoryWindow; + + //Packet history window that stores the time interval between the current and the last seq. + private final PacketHistoryWindow packetHistoryWindow; + + //for storing the arrival time of the last received data packet + private volatile long lastDataPacketArrivalTime=0; + + //largest received data packet sequence number(LRSN) + private volatile long largestReceivedSeqNumber=0; + + //ACK event related + + //last Ack number + private long lastAckNumber=0; + + //largest Ack number ever acknowledged by ACK2 + private volatile long largestAcknowledgedAckNumber=-1; + + //EXP event related + + //a variable to record number of continuous EXP time-out events + private volatile long expCount=0; + + /*records the time interval between each probing pair + compute the median packet pair interval of the last + 16 packet pair intervals (PI) and the estimate link capacity.(packet/s)*/ + private final PacketPairWindow packetPairWindow; + + //estimated link capacity + long estimateLinkCapacity; + // the packet arrival rate + long packetArrivalSpeed; + + //round trip time, calculated from ACK/ACK2 pairs + long roundTripTime=0; + //round trip time variance + long roundTripTimeVar=roundTripTime/2; + + //to check the ACK, NAK, or EXP timer + private long nextACK; + //microseconds to next ACK event + private long ackTimerInterval=Util.getSYNTime(); + + private long nextNAK; + //microseconds to next NAK event + private long nakTimerInterval=Util.getSYNTime(); + + private long nextEXP; + //microseconds to next EXP event + private long expTimerInterval=100*Util.getSYNTime(); + + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + + //buffer size for storing data + private final long bufferSize; + + //stores received packets to be sent + private final BlockingQueuehandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + logger.info("sendNAK:"+currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + logger.info("sendNAK List:"+sequenceNumbers.size()); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2c/00da54ff0eac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/00da54ff0eac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..0eb5a70 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/00da54ff0eac001710ff8a7c6bda0fb8 @@ -0,0 +1,107 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.util.HashMap; +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + @SuppressWarnings("rawtypes") + private final ReferenceQueue q = new ReferenceQueue(); + private volatile long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private final HashMap,Long> map=new HashMap,Long> (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + map.remove(k); + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + + /** + * 单例 + * @param point + * @return + */ + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + map.put(tmp, socket.getSocketID()); + if(num%10==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2c/30197d17d7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/30197d17d7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..8f0cb60 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/30197d17d7ac001716b9ca6d5abb90bc @@ -0,0 +1,270 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import udt.util.ReceiveBuffer; + +/** + * The UDTInputStream receives data blocks from the {@link UDTSocket} + * as they become available, and places them into an ordered, + * bounded queue (the flow window) for reading by the application + * + * + */ +public class UDTInputStream extends InputStream { + + //the socket owning this inputstream + private final UDTSocket socket; + + private final ReceiveBuffer receiveBuffer; + + //set to 'false' by the receiver when it gets a shutdown signal from the peer + //see the noMoreData() method + private final AtomicBoolean expectMoreData=new AtomicBoolean(true); + + private volatile boolean closed=false; + + private volatile boolean blocking=true; + + private volatile boolean hasData=false;//cd + + + + /** + * create a new {@link UDTInputStream} connected to the given socket + * @param socket - the {@link UDTSocket} + * @throws IOException + */ + public UDTInputStream(UDTSocket socket)throws IOException{ + this.socket=socket; + int capacity=socket!=null? 2 * socket.getSession().getFlowWindowSize() : 128 ; + long initialSequenceNum=socket!=null?socket.getSession().getInitialSequenceNumber():1; + receiveBuffer=new ReceiveBuffer(capacity,initialSequenceNum); + } + + private final byte[]single=new byte[1]; + + @Override + public int read()throws IOException{ + int b=0; + while(b==0) + b=read(single); + + if(b>0){ + return single[0]; + } + else { + return b; + } + } + + private AppData currentChunk=null; + //offset into currentChunk + int offset=0; + long id=-1; + @Override + public int read(byte[]target)throws IOException{ + try{ + int read=0; + updateCurrentChunk(false); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(blocking && read==0); + } + + if(read>0)return read; + if(closed)return -1; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; + //no more data + return -1; + + }catch(Exception ex){ + IOException e= new IOException(); + e.initCause(ex); + throw e; + } + } + + /** + * Reads the next valid chunk of application data from the queue
+ * + * In blocking mode,this method will block until data is available or the socket is closed, + * otherwise it will wait for at most 10 milliseconds. + * + * @throws InterruptedException + */ + private void updateCurrentChunk(boolean block)throws IOException{ + if(currentChunk!=null)return; + + while(true){ + try{ + if(block){ + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); + while (!closed && currentChunk==null){ + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); + } + } + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); + + }catch(InterruptedException ie){ + IOException ex=new IOException(); + ex.initCause(ie); + throw ex; + } + return; + } + } + + /** + * new application data + * @param data + * + */ + protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + hasData=true; + return receiveBuffer.offer(new AppData(sequenceNumber,data)); + } + + @Override + public void close()throws IOException{ + if(closed)return; + closed=true; + noMoreData(); + } + + public UDTSocket getSocket(){ + return socket; + } + + /** + * sets the blocking mode + * @param block + */ + public void setBlocking(boolean block){ + this.blocking=block; + } + + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + + /** + * notify the input stream that there is no more data + * @throws IOException + */ + protected void noMoreData()throws IOException{ + expectMoreData.set(false); + } + + /** + * 判断有没有数据进来 + * cd + * @return + */ + public boolean isHasData() + { + return hasData; + } + + /** + * used for storing application data and the associated + * sequence number in the queue in ascending order + */ + public static class AppData implements Comparable{ + final long sequenceNumber; + final byte[] data; + public AppData(long sequenceNumber, byte[]data){ + this.sequenceNumber=sequenceNumber; + this.data=data; + } + + @Override + public int compareTo(AppData o) { + return (int)(sequenceNumber-o.sequenceNumber); + } + + @Override + public String toString(){ + return sequenceNumber+"["+data.length+"]"; + } + + public long getSequenceNumber(){ + return sequenceNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2c/801fec2f59ac00171c63d91e40f02a62 b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/801fec2f59ac00171c63d91e40f02a62 new file mode 100644 index 0000000..d3acdc8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/801fec2f59ac00171c63d91e40f02a62 @@ -0,0 +1,152 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2c/b041f93e67a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/b041f93e67a800171a8482560d609ceb new file mode 100644 index 0000000..18970fd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/b041f93e67a800171a8482560d609ceb @@ -0,0 +1,64 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + UDTSocket find=null; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(find==null) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关闭 + find=list.get(i); + i=-1;//重新遍历 + } + } + else + { + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2c/d0baafa565a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/d0baafa565a800171a8482560d609ceb new file mode 100644 index 0000000..89ec2b8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2c/d0baafa565a800171a8482560d609ceb @@ -0,0 +1,25 @@ +/** + * + */ +package judp; + +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} +public +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2d/10bf61d937ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/2d/10bf61d937ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..5d7ec3d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2d/10bf61d937ac001710ff8a7c6bda0fb8 @@ -0,0 +1,100 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(len); + for(int i=0;iwaitDataLen&&readLen==0) + { + //等待时间长度,没有发送过接收过数据,则退出 + logger.info("缓冲时间到退出读取:"+socketID); + return -1; + } + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + + +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + flushTime=System.currentTimeMillis(); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2d/60a67df369a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/2d/60a67df369a800171a8482560d609ceb new file mode 100644 index 0000000..11c8053 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2d/60a67df369a800171a8482560d609ceb @@ -0,0 +1,113 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=accept(); + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2d/60cfdf2409ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/2d/60cfdf2409ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..d44ad69 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2d/60cfdf2409ac001710ff8a7c6bda0fb8 @@ -0,0 +1,99 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; + +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + @SuppressWarnings("rawtypes") + private final ReferenceQueue q = new ReferenceQueue(); + private volatile long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private final HashMap map=new HashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/200d3c4164a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/200d3c4164a800171a8482560d609ceb new file mode 100644 index 0000000..a3f8f02 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/200d3c4164a800171a8482560d609ceb @@ -0,0 +1,45 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + startGC(); + } + + public static synchronized SocketManager getInstance() { + + if (instance == null) { + + instance = new SocketManager(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/30535d40c5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/30535d40c5ad0017181ed9113883eda9 new file mode 100644 index 0000000..41c4b96 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/30535d40c5ad0017181ed9113883eda9 @@ -0,0 +1,522 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/4043e9f84fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/4043e9f84fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..75e9fa8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/4043e9f84fac001710ff8a7c6bda0fb8 @@ -0,0 +1,146 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i20) + { + //10秒后超时 + + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else + { + break; + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/603775eeb3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/603775eeb3ad0017181ed9113883eda9 new file mode 100644 index 0000000..332af7c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/603775eeb3ad0017181ed9113883eda9 @@ -0,0 +1,515 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + onAcknowledge(acknowledgement); + } + + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/6047b62203ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/6047b62203ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..98d3488 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/6047b62203ac001710ff8a7c6bda0fb8 @@ -0,0 +1,22 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + public SocketQueue(T referent) { + super(referent); + + } + + + public +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/b08f394dc5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/b08f394dc5ad0017181ed9113883eda9 new file mode 100644 index 0000000..5a0a0b0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/b08f394dc5ad0017181ed9113883eda9 @@ -0,0 +1,522 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/c0aa731ac5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/c0aa731ac5ad0017181ed9113883eda9 new file mode 100644 index 0000000..c53b0c3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/c0aa731ac5ad0017181ed9113883eda9 @@ -0,0 +1,516 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/f0a141dda3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/f0a141dda3ad0017181ed9113883eda9 new file mode 100644 index 0000000..088da1b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/f0a141dda3ad0017181ed9113883eda9 @@ -0,0 +1,43 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //192.168.30.128 + ReadXml rd=new ReadXml(); + String xml= rd.readXml(ReadXml.getPath()+"/config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("127.0.0.1", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2f/1088bc2468a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/1088bc2468a800171a8482560d609ceb new file mode 100644 index 0000000..cbf26ff --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/1088bc2468a800171a8482560d609ceb @@ -0,0 +1,77 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + i=-1;//重新遍历 + index=i; + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2f/2054ba4000ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/2054ba4000ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f5b7641 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/2054ba4000ac001710ff8a7c6bda0fb8 @@ -0,0 +1,14 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; + +/** + * @author jinyu + * + */ +public class SocketQueue extends ReferenceQueue { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2f/20ad410dc5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/20ad410dc5ad0017181ed9113883eda9 new file mode 100644 index 0000000..ad5c2f1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/20ad410dc5ad0017181ed9113883eda9 @@ -0,0 +1,516 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2f/804aa08d21ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/804aa08d21ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7a018d7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/804aa08d21ac001710ff8a7c6bda0fb8 @@ -0,0 +1,288 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + + +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + flushTime=System.currentTimeMillis(); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3/60d321ea61ac00171ca19969f19d2325 b/.metadata/.plugins/org.eclipse.core.resources/.history/3/60d321ea61ac00171ca19969f19d2325 new file mode 100644 index 0000000..1264aed --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3/60d321ea61ac00171ca19969f19d2325 @@ -0,0 +1,248 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + System.out.println("sendBlocking start"); + client.send(data); + r=data.length; + sumLen+=r; + System.out.println("sendBlocking end"); + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;isessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&stopped) + { + //已经正常关闭 + } + else + { + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + } + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/30/4057ad45c5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/30/4057ad45c5ad0017181ed9113883eda9 new file mode 100644 index 0000000..fdb132c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/30/4057ad45c5ad0017181ed9113883eda9 @@ -0,0 +1,522 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/30/a07a6f8a9aad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/30/a07a6f8a9aad0017181ed9113883eda9 new file mode 100644 index 0000000..71c0dcf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/30/a07a6f8a9aad0017181ed9113883eda9 @@ -0,0 +1,502 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/30/c0f68a50d7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/30/c0f68a50d7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..231b1be --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/30/c0f68a50d7ac001716b9ca6d5abb90bc @@ -0,0 +1,284 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + System.out.println("sendBlocking start"); + client.sendBlocking(data); + r=data.length; + sumLen+=r; + System.out.println("sendBlocking end"); + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i20) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + break; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else + { + break; + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/31/106f933126ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/31/106f933126ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..3acfe86 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/31/106f933126ac001710ff8a7c6bda0fb8 @@ -0,0 +1,89 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;ihandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + logger.info("haveNewData:失败"); + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + logger.info("largestReceivedSeqNumber:"+largestReceivedSeqNumber); + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + logger.info("sendNAK:"+currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + logger.info("sendNAK List:"+sequenceNumbers.size()); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/33/b04561b206ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/33/b04561b206ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..b4327ab --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/33/b04561b206ac001710ff8a7c6bda0fb8 @@ -0,0 +1,96 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; + +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + private long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/34/b06540c026ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/34/b06540c026ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..6d00dfb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/34/b06540c026ac001710ff8a7c6bda0fb8 @@ -0,0 +1,234 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + private int len=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData= PackagetSub.splitData(data); + for(int i=0;i list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取有数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + index=i; + i=-1;//重新遍历 + + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +/** + * 清除所有socket + */ +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/35/8092462f1eac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/35/8092462f1eac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f4e86f8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/35/8092462f1eac001710ff8a7c6bda0fb8 @@ -0,0 +1,27 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public DataStruct addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + struct.addData(data); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/36/106b6f256da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/36/106b6f256da800171a8482560d609ceb new file mode 100644 index 0000000..6d9a951 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/36/106b6f256da800171a8482560d609ceb @@ -0,0 +1,56 @@ +/** + * 文件名:TestSendFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpSendFile; + +/** + * + * 项目名称:judp + * 类名称:TestSendFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:25 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:25 + * 修改备注: + * @version + * + */ +public class TestSendFiles { + + /** + + * TODO(这里描述这个方法适用条件 – 可选) + + * @param name + + * @return + + * + + + */ + public static void main(String[] args) { + judpSendFile jsend=new judpSendFile("192.168.10.86",5555); + jsend.startSend(); + + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/36/406a1f2526ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/36/406a1f2526ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..07081d8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/36/406a1f2526ac001710ff8a7c6bda0fb8 @@ -0,0 +1,54 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + ss.close(); + break; + } + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/36/d0590bba1bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/36/d0590bba1bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..e65d360 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/36/d0590bba1bac001710ff8a7c6bda0fb8 @@ -0,0 +1,55 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + TimeUnit.SECONDS.sleep(1); + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/39/803bf78dceac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/39/803bf78dceac001716b9ca6d5abb90bc new file mode 100644 index 0000000..4d49a03 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/39/803bf78dceac001716b9ca6d5abb90bc @@ -0,0 +1,206 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isReadMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isReadMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/39/f089629426ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/39/f089629426ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..8816e0d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/39/f089629426ac001710ff8a7c6bda0fb8 @@ -0,0 +1,92 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + /** + * 接收数据写入文件 + */ + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + //空文件不会有数据 + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + break; + } + else + { + recData(); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3b/0009e5c7a3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/3b/0009e5c7a3ad0017181ed9113883eda9 new file mode 100644 index 0000000..5fa122b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3b/0009e5c7a3ad0017181ed9113883eda9 @@ -0,0 +1,36 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //192.168.30.128 + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("127.0.0.1", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3b/20158b335ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/3b/20158b335ca800171a8482560d609ceb new file mode 100644 index 0000000..0a33696 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3b/20158b335ca800171a8482560d609ceb @@ -0,0 +1,202 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + shutdown(); + } + } + + } + + }); + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3c/20d0ca0806ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/3c/20d0ca0806ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..2d2d921 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3c/20d0ca0806ac001710ff8a7c6bda0fb8 @@ -0,0 +1,96 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; + +import java.util.WeakHashMap; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + private long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3d/a0e3d71e22ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/3d/a0e3d71e22ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f508d95 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3d/a0e3d71e22ac001710ff8a7c6bda0fb8 @@ -0,0 +1,212 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + byte[] buf=new byte[bufSize];//数据区 + int index=0; + int r=0; + try { + while(true) + { + r=client.read(readBytes); + if(r==-1) + { + break; + } + else + { + if(r<=bufSize) + { + //result=new byte[r]; + //System.arraycopy(readBytes, 0, result, 0, r); + if(index+r hash=new ConcurrentHashMap(); +// private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + int num=0; + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + num++; + // + if(!list.isEmpty()) + { + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long startTime=System.currentTimeMillis(); + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-startTime)/1000); + } + catch(Exception ex) + { + + } + log.info("文件接收速度:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3d/d0dec61a6aa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/3d/d0dec61a6aa800171a8482560d609ceb new file mode 100644 index 0000000..b411550 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3d/d0dec61a6aa800171a8482560d609ceb @@ -0,0 +1,113 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3e/105906a604ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/105906a604ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..3acb753 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/105906a604ac001710ff8a7c6bda0fb8 @@ -0,0 +1,86 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3e/10c01b9bd8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/10c01b9bd8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..5cfcf83 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/10c01b9bd8ac001716b9ca6d5abb90bc @@ -0,0 +1,152 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private boolean isRWMaster=true;//与默认值一致 +private boolean islagerRead=false; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + try { + csocket.getInputStream().setLargeRead(islagerRead); + csocket.getInputStream().resetBufMaster(isRWMaster); + } catch (IOException e) { + e.printStackTrace(); + } + + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + *设置大数据读取才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + this.isRWMaster=isRead; + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.islagerRead=islarge; +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3e/90c8f6fe1bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/90c8f6fe1bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..3e743d5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/90c8f6fe1bac001710ff8a7c6bda0fb8 @@ -0,0 +1,28 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] data; +public long id; +public DataStruct(int num) +{ + data=new byte[num][]; +} +public void addData(byte[]data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + int index=buf.getInt(); + int dataLen=buf.getInt(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3f/0095c3b32bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/0095c3b32bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..6441e79 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/0095c3b32bac001710ff8a7c6bda0fb8 @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int sumNum=0; +private volatile int sumLen=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} + +/** + * 整理数据 + * @return + */ +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sumLen==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + log.info("发送:"+f.getName()+","+bufSize); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + log.info("发送:"+f.getName()+","+count); + } + + } + long endTime=System.currentTimeMillis(); + client.close(); + dis.close(); + long speed=fLen/((endTime-startTime)/1000); + log.info("发送完成:"+f.getName()+",平均速度(M/S):"+speed/1024/1024); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3f/20ae3effb7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/20ae3effb7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..a658247 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/20ae3effb7ac001716b9ca6d5abb90bc @@ -0,0 +1,193 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.KeepAlive; +import udt.packets.Shutdown; + +/** + * server side session in client-server mode + */ +public class ServerSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ServerSession.class.getName()); + + private final UDPEndPoint endPoint; + + //last received packet (for testing purposes) + private UDTPacket lastPacket; + + + public ServerSession(DatagramPacket dp, UDPEndPoint endPoint)throws SocketException,UnknownHostException{ + super("ServerSession localPort="+endPoint.getLocalPort()+" peer="+dp.getAddress()+":"+dp.getPort(),new Destination(dp.getAddress(),dp.getPort())); + this.endPoint=endPoint; + logger.info("Created "+toString()+" talking to "+dp.getAddress()+":"+dp.getPort()); + } + + int n_handshake=0; + + @Override + public void received(UDTPacket packet, Destination peer){ + lastPacket=packet; + + if(packet instanceof ConnectionHandshake) { + ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; + logger.info("Received "+connectionHandshake); + + if (getState()<=ready){ + destination.setSocketID(connectionHandshake.getSocketID()); + + if(getState()<=handshaking){ + setState(handshaking); + } + try{ + handleHandShake(connectionHandshake); + n_handshake++; + try{ + setState(ready); + socket=new UDTSocket(endPoint, this); + cc.init(); + }catch(Exception uhe){ + //session is invalid + logger.log(Level.SEVERE,"",uhe); + setState(invalid); + } + }catch(IOException ex){ + //session invalid + logger.log(Level.WARNING,"Error processing ConnectionHandshake",ex); + setState(invalid); + } + return; + } + + }else if(packet instanceof KeepAlive) { + socket.getReceiver().resetEXPTimer(); + active = true; + return; + } + + if(getState()== ready) { + active = true; + + if (packet instanceof KeepAlive) { + //nothing to do here + return; + }else if (packet instanceof Shutdown) { + try{ + socket.getReceiver().stop(); + }catch(IOException ex){ + logger.log(Level.WARNING,"",ex); + } + setState(shutdown); + System.out.println("SHUTDOWN ***"); + active = false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + + else{ + try{ + long seqNo=packet.getPacketSequenceNumber(); + if(seqNo!=-1) + logger.info("DataPacket:"+seqNo); + if(packet.forSender()){ + socket.getSender().receive(packet); + }else{ + socket.getReceiver().receive(packet); + } + }catch(Exception ex){ + //session invalid + logger.log(Level.SEVERE,"",ex); + setState(invalid); + } + } + return; + + } + + + } + + /** + * for testing use only + */ + UDTPacket getLastPacket(){ + return lastPacket; + } + + /** + * handle the connection handshake:
+ *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3f/90252382e1ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/90252382e1ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..f034620 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/90252382e1ac001716b9ca6d5abb90bc @@ -0,0 +1,193 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/timespan/1000; + } + speed=sumBytes/(()/1000); + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3f/a091f71264a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/a091f71264a800171a8482560d609ceb new file mode 100644 index 0000000..33c1e19 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/a091f71264a800171a8482560d609ceb @@ -0,0 +1,27 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private ConcurrentHashMap hash=new ConcurrentHashMap(); +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3f/d057016d64a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/d057016d64a800171a8482560d609ceb new file mode 100644 index 0000000..e21ff11 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/d057016d64a800171a8482560d609ceb @@ -0,0 +1,50 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + // TODO Auto-generated method stub + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4/30a058a9e7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/4/30a058a9e7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..cb3a344 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4/30a058a9e7ac001716b9ca6d5abb90bc @@ -0,0 +1,36 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //192.168.30.128 + RecviceFiles rec=new RecviceFiles(); + String dir="/home/jinyu/recFiles"; + rec.setDir(dir); + rec.start("192.168.30.128", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4/40be8a05e0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/4/40be8a05e0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..0ff7251 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4/40be8a05e0ac001716b9ca6d5abb90bc @@ -0,0 +1,189 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long startTime=System.currentTimeMillis(); + long lastTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-lastTime)/1000); + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4/60fff865d8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/4/60fff865d8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..d9caf81 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4/60fff865d8ac001716b9ca6d5abb90bc @@ -0,0 +1,358 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;ihandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + logger.info("largestReceivedSeqNumber:"+largestReceivedSeqNumber); + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/40/a02a6e9dcfac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/40/a02a6e9dcfac001716b9ca6d5abb90bc new file mode 100644 index 0000000..fa7a396 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/40/a02a6e9dcfac001716b9ca6d5abb90bc @@ -0,0 +1,232 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 + if(highestReadSequenceNumber+10){ + int len=Math.min(bb.remaining(),chunksize); + byte[]chunk=new byte[len]; + bb.get(chunk); + DataPacket packet=new DataPacket(); + seqNo=sender.getNextSequenceNumber(); + packet.setPacketSequenceNumber(seqNo); + packet.setSession(session); + packet.setDestinationID(session.getDestination().getSocketID()); + packet.setData(chunk); + System.out.println("sender sendUdtPacket1"); + //put the packet into the send queue + if(!sender.sendUdtPacket(packet, timeout, units)){ + throw new IOException("Queue full"); + } + System.out.println("sender sendUdtPacket2"); + } + if(length>0)active=true; + System.out.println("sender sendUdtPacket out"); + } + /** + * will block until the outstanding packets have really been sent out + * and acknowledged + */ + protected void flush() throws InterruptedException{ + if(!active)return; + final long seqNo=sender.getCurrentSequenceNumber(); + if(seqNo<0)throw new IllegalStateException(); + while(!sender.isSentOut(seqNo)){ + Thread.sleep(5); + } + if(seqNo>-1){ + //wait until data has been sent out and acknowledged + while(active && !sender.haveAcknowledgementFor(seqNo)){ + sender.waitForAck(seqNo); + } + } + //TODO need to check if we can pause the sender... + //sender.pause(); + } + + //writes and wait for ack + protected void doWriteBlocking(byte[]data)throws IOException, InterruptedException{ + doWrite(data); + System.out.println("flush"); + flush(); + System.out.println("flush out"); + } + + /** + * close the connection + * @throws IOException + */ + public void close()throws IOException{ + if(inputStream!=null)inputStream.close(); + if(outputStream!=null)outputStream.close(); + active=false; + close=true; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/41/f07d59bd1cac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/41/f07d59bd1cac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..a227404 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/41/f07d59bd1cac001710ff8a7c6bda0fb8 @@ -0,0 +1,44 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer; +public long id; +private volatile int num=0; +private volatile int sum=0; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + + } +} +public boolean addData(byte[]data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + int index=buf.getInt(); + dataLen=buf.getInt(); + byte[] tmp=new byte[buf.limit()-buf.position()]; + buf.get(tmp); + buffer[index]=tmp; + num++; +} + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/42/101d91fd26ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/42/101d91fd26ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..500993a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/42/101d91fd26ac001710ff8a7c6bda0fb8 @@ -0,0 +1,234 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData= PackagetSub.splitData(data); + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + if(highestReadSequenceNumber+1 hash=new ConcurrentHashMap(); + private ConcurrentLinkedQueue queue=new ConcurrentLinkedQueue(); +public boolean addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + boolean r= struct.addData(data); + if(r) + { + byte[]result =struct.getData(); + byte[] tmp=new byte[result.length]; + System.arraycopy(result, 0, tmp, 0, tmp.length); + queue.offer(tmp); + struct.clear(); + hash.remove(id); + } + return r; + +} +public byte[] getData() +{ + return queue.poll(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/44/00022a6de4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/44/00022a6de4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..7848a53 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/44/00022a6de4ac001716b9ca6d5abb90bc @@ -0,0 +1,219 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/44/10c21fc9d6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/44/10c21fc9d6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..4c5925c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/44/10c21fc9d6ac001716b9ca6d5abb90bc @@ -0,0 +1,248 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + System.out.println("sendBlocking start"); + client.sendBlocking(data); + r=data.length; + sumLen+=r; + System.out.println("sendBlocking end"); + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;isessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); +// session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest);//cd + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&stopped) + { + //cd + //已经正常关闭 + } + else + { + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + } + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/44/e0b7669b5ba800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/44/e0b7669b5ba800171a8482560d609ceb new file mode 100644 index 0000000..f6ab2a2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/44/e0b7669b5ba800171a8482560d609ceb @@ -0,0 +1,196 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + // TODO Auto-generated method stub + + } + + }) + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/45/30c1c047b5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/45/30c1c047b5ad0017181ed9113883eda9 new file mode 100644 index 0000000..f72f300 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/45/30c1c047b5ad0017181ed9113883eda9 @@ -0,0 +1,519 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/45/80fb200424ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/45/80fb200424ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7b49c56 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/45/80fb200424ac001710ff8a7c6bda0fb8 @@ -0,0 +1,324 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=PackagetSub.split(data); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+); + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/46/e0878eb7f8ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/46/e0878eb7f8ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..a644cde --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/46/e0878eb7f8ab001710ff8a7c6bda0fb8 @@ -0,0 +1,347 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.PacketFactory; +import udt.util.UDTThreadFactory; + +/** + * the UDPEndpoint takes care of sending and receiving UDP network packets, + * dispatching them to the correct {@link UDTSession} + */ +public class UDPEndPoint { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private final int port; + + private final DatagramSocket dgSocket; + + //active sessions keyed by socket ID + private final Mapsessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + } + } + }catch(SocketException ex){ + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/47/007297c0b8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/47/007297c0b8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..8c45dc5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/47/007297c0b8ac001716b9ca6d5abb90bc @@ -0,0 +1,602 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ControlPacket; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.packets.Shutdown; +import udt.packets.ControlPacket.ControlPacketType; +import udt.receiver.AckHistoryEntry; +import udt.receiver.AckHistoryWindow; +import udt.receiver.PacketHistoryWindow; +import udt.receiver.PacketPairWindow; +import udt.receiver.ReceiverLossList; +import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + +/** + * receiver part of a UDT entity + * @see UDTSender + */ +public class UDTReceiver { + + private static final Logger logger=Logger.getLogger(UDTReceiver.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //record seqNo of detected lostdata and latest feedback time + private final ReceiverLossList receiverLossList; + + //record each sent ACK and the sent time + private final AckHistoryWindow ackHistoryWindow; + + //Packet history window that stores the time interval between the current and the last seq. + private final PacketHistoryWindow packetHistoryWindow; + + //for storing the arrival time of the last received data packet + private volatile long lastDataPacketArrivalTime=0; + + //largest received data packet sequence number(LRSN) + private volatile long largestReceivedSeqNumber=0; + + //ACK event related + + //last Ack number + private long lastAckNumber=0; + + //largest Ack number ever acknowledged by ACK2 + private volatile long largestAcknowledgedAckNumber=-1; + + //EXP event related + + //a variable to record number of continuous EXP time-out events + private volatile long expCount=0; + + /*records the time interval between each probing pair + compute the median packet pair interval of the last + 16 packet pair intervals (PI) and the estimate link capacity.(packet/s)*/ + private final PacketPairWindow packetPairWindow; + + //estimated link capacity + long estimateLinkCapacity; + // the packet arrival rate + long packetArrivalSpeed; + + //round trip time, calculated from ACK/ACK2 pairs + long roundTripTime=0; + //round trip time variance + long roundTripTimeVar=roundTripTime/2; + + //to check the ACK, NAK, or EXP timer + private long nextACK; + //microseconds to next ACK event + private long ackTimerInterval=Util.getSYNTime(); + + private long nextNAK; + //microseconds to next NAK event + private long nakTimerInterval=Util.getSYNTime(); + + private long nextEXP; + //microseconds to next EXP event + private long expTimerInterval=100*Util.getSYNTime(); + + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + + //buffer size for storing data + private final long bufferSize; + + //stores received packets to be sent + private final BlockingQueuehandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/47/d00bbfdca0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/47/d00bbfdca0ad0017181ed9113883eda9 new file mode 100644 index 0000000..377ac17 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/47/d00bbfdca0ad0017181ed9113883eda9 @@ -0,0 +1,43 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + SendFiles send=new SendFiles("192.168.30.128", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/48/d0a3f354a2ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/48/d0a3f354a2ad0017181ed9113883eda9 new file mode 100644 index 0000000..3068e79 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/48/d0a3f354a2ad0017181ed9113883eda9 @@ -0,0 +1,55 @@ +/** + * + */ +package net.File; + +import java.io.File; +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + String path = TestSendFiles.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + int firstIndex = path.lastIndexOf(System.getProperty("path.separator")) + 1; + int lastIndex = path.lastIndexOf(File.separator) + 1; + path = path.substring(firstIndex, lastIndex); + ReadXml rd=new ReadXml(); + String xml= rd.readXml(path+"/config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + SendFiles send=new SendFiles(config[0], Integer.valueOf(config[1])); + FilesWatch watch=new FilesWatch(); + String dir=config[2]; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/48/d0b6053b5ba800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/48/d0b6053b5ba800171a8482560d609ceb new file mode 100644 index 0000000..5969962 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/48/d0b6053b5ba800171a8482560d609ceb @@ -0,0 +1,174 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/49/3039da0c69a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/49/3039da0c69a800171a8482560d609ceb new file mode 100644 index 0000000..5697cf1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/49/3039da0c69a800171a8482560d609ceb @@ -0,0 +1,81 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/49/607bc94804ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/49/607bc94804ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..18dafab --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/49/607bc94804ac001710ff8a7c6bda0fb8 @@ -0,0 +1,71 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (SocketReference) q.remove()) != null) { + long id=k.getid(); + + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4a/80cbba742aad001713e0de43c08806fd b/.metadata/.plugins/org.eclipse.core.resources/.history/4a/80cbba742aad001713e0de43c08806fd new file mode 100644 index 0000000..998e39b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4a/80cbba742aad001713e0de43c08806fd @@ -0,0 +1,189 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.SocketException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.SequenceNumber; + +/** + * Client side of a client-server UDT connection. + * Once established, the session provides a valid {@link UDTSocket}. + */ +public class ClientSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private UDPEndPoint endPoint; + + public ClientSession(UDPEndPoint endPoint, Destination dest)throws SocketException{ + super("ClientSession localPort="+endPoint.getLocalPort(),dest); + this.endPoint=endPoint; + logger.info("Created "+toString()); + } + + /** + * send connection handshake until a reply from server is received + * TODO check for timeout + * @throws InterruptedException + * @throws IOException + */ + + public void connect() throws InterruptedException,IOException{ + int n=0; + + while(getState()!=ready){ + + sendHandShake(); + if(getState()==invalid)throw new IOException("Can't connect!"); + n++; + if(getState()!=ready)Thread.sleep(500); + } + + cc.init(); + logger.info("Connected, "+n+" handshake packets sent"); + } + + @Override + public void received(UDTPacket packet, Destination peer) { + + lastPacket=packet; + + if (packet instanceof ConnectionHandshake) { + ConnectionHandshake hs=(ConnectionHandshake)packet; + + logger.info("Received connection handshake from "+peer+"\n"+hs); + + if (getState()!=ready) { + if(hs.getConnectionType()==1){ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + sendConfirmation(hs); + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + else{ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + setState(ready); + TimeUnit.MILLISECONDS.sleep(50); + logger.info("初始序列置回:"+hs.getInitialSeqNo()); + this.setInitialSequenceNumber(hs.getInitialSeqNo());//cd 必须重置 + socket=new UDTSocket(endPoint,this); + + + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + } + } + + if(getState() == ready) { + + if(packet instanceof Shutdown){ + setState(shutdown); + active=false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + active = true; + try{ + if(packet.forSender()){ + socket.getSender().receive(lastPacket); + }else{ + socket.getReceiver().receive(lastPacket); + } + }catch(Exception ex){ + //session is invalid + logger.log(Level.SEVERE,"Error in "+toString(),ex); + setState(invalid); + } + return; + } + } + + + //handshake for connect + protected void sendHandShake()throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(ConnectionHandshake.CONNECTION_TYPE_REGULAR); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + long initialSequenceNo=SequenceNumber.random(); + setInitialSequenceNumber(initialSequenceNo); + handshake.setInitialSeqNo(initialSequenceNo); + handshake.setPacketSize(getDatagramSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending "+handshake); + endPoint.doSend(handshake); + } + + //2nd handshake for connect + protected void sendConfirmation(ConnectionHandshake hs)throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(-1); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + handshake.setInitialSeqNo(hs.getInitialSeqNo()); + handshake.setPacketSize(hs.getPacketSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending confirmation "+handshake); + endPoint.doSend(handshake); + } + + + public UDTPacket getLastPkt(){ + return lastPacket; + } + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4a/d05deaacb8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/4a/d05deaacb8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..8cfe07a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4a/d05deaacb8ac001716b9ca6d5abb90bc @@ -0,0 +1,601 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ControlPacket; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.packets.Shutdown; +import udt.packets.ControlPacket.ControlPacketType; +import udt.receiver.AckHistoryEntry; +import udt.receiver.AckHistoryWindow; +import udt.receiver.PacketHistoryWindow; +import udt.receiver.PacketPairWindow; +import udt.receiver.ReceiverLossList; +import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + +/** + * receiver part of a UDT entity + * @see UDTSender + */ +public class UDTReceiver { + + private static final Logger logger=Logger.getLogger(UDTReceiver.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //record seqNo of detected lostdata and latest feedback time + private final ReceiverLossList receiverLossList; + + //record each sent ACK and the sent time + private final AckHistoryWindow ackHistoryWindow; + + //Packet history window that stores the time interval between the current and the last seq. + private final PacketHistoryWindow packetHistoryWindow; + + //for storing the arrival time of the last received data packet + private volatile long lastDataPacketArrivalTime=0; + + //largest received data packet sequence number(LRSN) + private volatile long largestReceivedSeqNumber=0; + + //ACK event related + + //last Ack number + private long lastAckNumber=0; + + //largest Ack number ever acknowledged by ACK2 + private volatile long largestAcknowledgedAckNumber=-1; + + //EXP event related + + //a variable to record number of continuous EXP time-out events + private volatile long expCount=0; + + /*records the time interval between each probing pair + compute the median packet pair interval of the last + 16 packet pair intervals (PI) and the estimate link capacity.(packet/s)*/ + private final PacketPairWindow packetPairWindow; + + //estimated link capacity + long estimateLinkCapacity; + // the packet arrival rate + long packetArrivalSpeed; + + //round trip time, calculated from ACK/ACK2 pairs + long roundTripTime=0; + //round trip time variance + long roundTripTimeVar=roundTripTime/2; + + //to check the ACK, NAK, or EXP timer + private long nextACK; + //microseconds to next ACK event + private long ackTimerInterval=Util.getSYNTime(); + + private long nextNAK; + //microseconds to next NAK event + private long nakTimerInterval=Util.getSYNTime(); + + private long nextEXP; + //microseconds to next EXP event + private long expTimerInterval=100*Util.getSYNTime(); + + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + + //buffer size for storing data + private final long bufferSize; + + //stores received packets to be sent + private final BlockingQueuehandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4a/d0c629a9cdac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/4a/d0c629a9cdac001716b9ca6d5abb90bc new file mode 100644 index 0000000..74d5c2d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4a/d0c629a9cdac001716b9ca6d5abb90bc @@ -0,0 +1,205 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isReadMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isReadMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4b/a035f5deb4ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/a035f5deb4ad0017181ed9113883eda9 new file mode 100644 index 0000000..1bcb149 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/a035f5deb4ad0017181ed9113883eda9 @@ -0,0 +1,515 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4b/a0ad7bad60a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/a0ad7bad60a800171a8482560d609ceb new file mode 100644 index 0000000..d270f29 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/a0ad7bad60a800171a8482560d609ceb @@ -0,0 +1,268 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import udt.util.ReceiveBuffer; + +/** + * The UDTInputStream receives data blocks from the {@link UDTSocket} + * as they become available, and places them into an ordered, + * bounded queue (the flow window) for reading by the application + * + * + */ +public class UDTInputStream extends InputStream { + + //the socket owning this inputstream + private final UDTSocket socket; + + private final ReceiveBuffer receiveBuffer; + + //set to 'false' by the receiver when it gets a shutdown signal from the peer + //see the noMoreData() method + private final AtomicBoolean expectMoreData=new AtomicBoolean(true); + + private volatile boolean closed=false; + + private volatile boolean blocking=true; + + private volatile boolean hasData=false;//cd + + + + /** + * create a new {@link UDTInputStream} connected to the given socket + * @param socket - the {@link UDTSocket} + * @throws IOException + */ + public UDTInputStream(UDTSocket socket)throws IOException{ + this.socket=socket; + int capacity=socket!=null? 2 * socket.getSession().getFlowWindowSize() : 128 ; + long initialSequenceNum=socket!=null?socket.getSession().getInitialSequenceNumber():1; + receiveBuffer=new ReceiveBuffer(capacity,initialSequenceNum); + } + + private final byte[]single=new byte[1]; + + @Override + public int read()throws IOException{ + int b=0; + while(b==0) + b=read(single); + + if(b>0){ + return single[0]; + } + else { + return b; + } + } + + private AppData currentChunk=null; + //offset into currentChunk + int offset=0; + long id=-1; + @Override + public int read(byte[]target)throws IOException{ + try{ + int read=0; + updateCurrentChunk(false); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(blocking && read==0); + } + + if(read>0)return read; + if(closed)return -1; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; + //no more data + return -1; + + }catch(Exception ex){ + IOException e= new IOException(); + e.initCause(ex); + throw e; + } + } + + /** + * Reads the next valid chunk of application data from the queue
+ * + * In blocking mode,this method will block until data is available or the socket is closed, + * otherwise it will wait for at most 10 milliseconds. + * + * @throws InterruptedException + */ + private void updateCurrentChunk(boolean block)throws IOException{ + if(currentChunk!=null)return; + + while(true){ + try{ + if(block){ + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); + while (!closed && currentChunk==null){ + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); + } + } + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); + + }catch(InterruptedException ie){ + IOException ex=new IOException(); + ex.initCause(ie); + throw ex; + } + return; + } + } + + /** + * new application data + * @param data + * + */ + protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + return receiveBuffer.offer(new AppData(sequenceNumber,data)); + } + + @Override + public void close()throws IOException{ + if(closed)return; + closed=true; + noMoreData(); + } + + public UDTSocket getSocket(){ + return socket; + } + + /** + * sets the blocking mode + * @param block + */ + public void setBlocking(boolean block){ + this.blocking=block; + } + + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + + /** + * notify the input stream that there is no more data + * @throws IOException + */ + protected void noMoreData()throws IOException{ + expectMoreData.set(false); + } + + /** + * 判断有没有数据进来 + * @return + */ + public boolean isHasData() + { + return hasData; + } + + /** + * used for storing application data and the associated + * sequence number in the queue in ascending order + */ + public static class AppData implements Comparable{ + final long sequenceNumber; + final byte[] data; + public AppData(long sequenceNumber, byte[]data){ + this.sequenceNumber=sequenceNumber; + this.data=data; + } + + @Override + public int compareTo(AppData o) { + return (int)(sequenceNumber-o.sequenceNumber); + } + + @Override + public String toString(){ + return sequenceNumber+"["+data.length+"]"; + } + + public long getSequenceNumber(){ + return sequenceNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4c/00556ecf13ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/4c/00556ecf13ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..1590f39 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4c/00556ecf13ac001710ff8a7c6bda0fb8 @@ -0,0 +1,27 @@ +package Test; + +import java.util.concurrent.TimeUnit; + +import judp.judpClient; + +public class TestClient { + + public static void main(String[] args) { + while(true) + { + judpClient client=new judpClient(); + client.connect("192.168.30.128", 5555); + byte[]data=("hello word "+System.currentTimeMillis()).getBytes(); + client.sendData(data); + client.close(); + try { + System.out.println("等待"); + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4c/f007c03509ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/4c/f007c03509ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..188ea86 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4c/f007c03509ac001710ff8a7c6bda0fb8 @@ -0,0 +1,99 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.util.HashMap; +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + @SuppressWarnings("rawtypes") + private final ReferenceQueue q = new ReferenceQueue(); + private volatile long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private final HashMap,Long> map=new HashMap,Long> (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4c/f03eaf6868a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/4c/f03eaf6868a800171a8482560d609ceb new file mode 100644 index 0000000..e87b7bf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4c/f03eaf6868a800171a8482560d609ceb @@ -0,0 +1,70 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + entry.getValue() + } + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4c/f0982c98e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/4c/f0982c98e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..b074331 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4c/f0982c98e4ac001716b9ca6d5abb90bc @@ -0,0 +1,223 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4d/400ac46406ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/4d/400ac46406ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7d3d629 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4d/400ac46406ac001710ff8a7c6bda0fb8 @@ -0,0 +1,70 @@ +/** + * + */ +package Test; + +import java.util.concurrent.TimeUnit; + +import judp.judpServer; +import judp.judpSocket; + +/** + * @author jinyu + * + */ +public class TestServer { + public static void main(String[] args) { + + judpServer server=new judpServer("127.0.0.1",5555); + server.start(); + while(true) + { + judpSocket socket=server.accept(); + // + + Thread rec=new Thread(new Runnable() { + @Override + public void run() { + try + { + byte[] data=new byte[1024]; + int r=0; + while(r!=-1) + { + r=socket.readData(data); + if(r==0) + { + + try { + TimeUnit.MILLISECONDS.sleep(100); + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if(r==-1) + { + System.out.println("读取-1退出"); + break; + } + byte[]tmp=new byte[r]; + System.arraycopy(data, 0, tmp, 0, r); + System.out.println(new String(tmp)); + + } + //socket.close(); + } + catch(Exception ex) + { + ex.printStackTrace(); + } + }} + ); + rec.setDaemon(true); + rec.start(); + + } + + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4d/b0a68230f7ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/4d/b0a68230f7ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7e0f55b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4d/b0a68230f7ab001710ff8a7c6bda0fb8 @@ -0,0 +1,130 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + for(int i=0;i20) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4e/903b8e7ad6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/4e/903b8e7ad6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..3c5fe39 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4e/903b8e7ad6ac001716b9ca6d5abb90bc @@ -0,0 +1,279 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取;也要外部快速读取 + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + // cd + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + + if(readPosition==size) + {readPosition=0; + if(this.islagerRead) + { + //cd + clearDeHash(this.size-leftNum); + } + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4e/b0d52a15e0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/4e/b0d52a15e0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..72ae1cb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4e/b0d52a15e0ac001716b9ca6d5abb90bc @@ -0,0 +1,188 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-lastTime)/1000); + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度M/S:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4f/200a00ac60a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/4f/200a00ac60a800171a8482560d609ceb new file mode 100644 index 0000000..0bad692 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4f/200a00ac60a800171a8482560d609ceb @@ -0,0 +1,262 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import udt.util.ReceiveBuffer; + +/** + * The UDTInputStream receives data blocks from the {@link UDTSocket} + * as they become available, and places them into an ordered, + * bounded queue (the flow window) for reading by the application + * + * + */ +public class UDTInputStream extends InputStream { + + //the socket owning this inputstream + private final UDTSocket socket; + + private final ReceiveBuffer receiveBuffer; + + //set to 'false' by the receiver when it gets a shutdown signal from the peer + //see the noMoreData() method + private final AtomicBoolean expectMoreData=new AtomicBoolean(true); + + private volatile boolean closed=false; + + private volatile boolean blocking=true; + + private volatile boolean hasData=false;//cd + + + + /** + * create a new {@link UDTInputStream} connected to the given socket + * @param socket - the {@link UDTSocket} + * @throws IOException + */ + public UDTInputStream(UDTSocket socket)throws IOException{ + this.socket=socket; + int capacity=socket!=null? 2 * socket.getSession().getFlowWindowSize() : 128 ; + long initialSequenceNum=socket!=null?socket.getSession().getInitialSequenceNumber():1; + receiveBuffer=new ReceiveBuffer(capacity,initialSequenceNum); + } + + private final byte[]single=new byte[1]; + + @Override + public int read()throws IOException{ + int b=0; + while(b==0) + b=read(single); + + if(b>0){ + return single[0]; + } + else { + return b; + } + } + + private AppData currentChunk=null; + //offset into currentChunk + int offset=0; + long id=-1; + @Override + public int read(byte[]target)throws IOException{ + try{ + int read=0; + updateCurrentChunk(false); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(blocking && read==0); + } + + if(read>0)return read; + if(closed)return -1; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; + //no more data + return -1; + + }catch(Exception ex){ + IOException e= new IOException(); + e.initCause(ex); + throw e; + } + } + + /** + * Reads the next valid chunk of application data from the queue
+ * + * In blocking mode,this method will block until data is available or the socket is closed, + * otherwise it will wait for at most 10 milliseconds. + * + * @throws InterruptedException + */ + private void updateCurrentChunk(boolean block)throws IOException{ + if(currentChunk!=null)return; + + while(true){ + try{ + if(block){ + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); + while (!closed && currentChunk==null){ + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); + } + } + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); + + }catch(InterruptedException ie){ + IOException ex=new IOException(); + ex.initCause(ie); + throw ex; + } + return; + } + } + + /** + * new application data + * @param data + * + */ + protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + return receiveBuffer.offer(new AppData(sequenceNumber,data)); + } + + @Override + public void close()throws IOException{ + if(closed)return; + closed=true; + noMoreData(); + } + + public UDTSocket getSocket(){ + return socket; + } + + /** + * sets the blocking mode + * @param block + */ + public void setBlocking(boolean block){ + this.blocking=block; + } + + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + + /** + * notify the input stream that there is no more data + * @throws IOException + */ + protected void noMoreData()throws IOException{ + expectMoreData.set(false); + } + + /** + * used for storing application data and the associated + * sequence number in the queue in ascending order + */ + public static class AppData implements Comparable{ + final long sequenceNumber; + final byte[] data; + public AppData(long sequenceNumber, byte[]data){ + this.sequenceNumber=sequenceNumber; + this.data=data; + } + + @Override + public int compareTo(AppData o) { + return (int)(sequenceNumber-o.sequenceNumber); + } + + @Override + public String toString(){ + return sequenceNumber+"["+data.length+"]"; + } + + public long getSequenceNumber(){ + return sequenceNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + public boolean isHasData() + { + return hasData + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4f/305dcf6953ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/4f/305dcf6953ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..9b12080 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4f/305dcf6953ac001710ff8a7c6bda0fb8 @@ -0,0 +1,337 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + startGC(); + } + + public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/50/002264c122ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/50/002264c122ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..04e0139 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/50/002264c122ac001710ff8a7c6bda0fb8 @@ -0,0 +1,218 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * 读取数据 + * 只和split发送对应 + * @return + */ + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(client.isClose()) + { + return null; + } + r=client.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; + } + public int read(byte[]data) + { + try { + return client.read(data); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return -1; + } + + /** + * 关闭 + */ + public void close() + { + if(client!=null) + { + if(sumLen==0) + { + //没有发送数据 + //立即关闭 + try { + if(!client.isClose()) + client.shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + //开始缓存 + //SocketManager.getInstance().add(client); + if(!client.isClose()) + client.close(); + } + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/50/10970a0ca1ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/50/10970a0ca1ad0017181ed9113883eda9 new file mode 100644 index 0000000..8aad23a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/50/10970a0ca1ad0017181ed9113883eda9 @@ -0,0 +1,50 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + ReadXml rd=new ReadXml(); + String xml= rd.readXml("config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + SendFiles send=new SendFiles("192.168.30.128", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/50/300b00e08ead0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/50/300b00e08ead0017181ed9113883eda9 new file mode 100644 index 0000000..a927104 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/50/300b00e08ead0017181ed9113883eda9 @@ -0,0 +1,89 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.logging.Logger; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +private static final Logger logger=Logger.getLogger(judpGroupSocket.class.getName()); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取有数据socket + * 并且移除其它无用socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + index=i; + i=-1;//重新遍历 + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + logger.info("移除无用socket:"+id); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +/** + * 清除所有socket + */ +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/50/6044e0b534ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/50/6044e0b534ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ead2099 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/50/6044e0b534ac001710ff8a7c6bda0fb8 @@ -0,0 +1,338 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + if(highestReadSequenceNumber+120) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else + { + break; + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/52/a0e88386d6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/52/a0e88386d6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..1d7aad2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/52/a0e88386d6ac001716b9ca6d5abb90bc @@ -0,0 +1,283 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取;也要外部快速读取 + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + // cd + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + + if(readPosition==size) + {readPosition=0; + if(this.islagerRead) + { + //cd + clearDeHash(this.size-leftNum); + } + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } + public void setlargeRead(boolean islarge) + { + this.islagerRead=islarge; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/53/60e8bdb026ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/53/60e8bdb026ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..412b002 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/53/60e8bdb026ac001710ff8a7c6bda0fb8 @@ -0,0 +1,234 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + private int len=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData= PackagetSub.split(data); + for(int i=0;i=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/54/f09c3717a1ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/54/f09c3717a1ad0017181ed9113883eda9 new file mode 100644 index 0000000..dcf9df5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/54/f09c3717a1ad0017181ed9113883eda9 @@ -0,0 +1,50 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + ReadXml rd=new ReadXml(); + String xml= rd.readXml("config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + SendFiles send=new SendFiles(config[0], Integer.valueOf(config[1])); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/55/2001542903ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/55/2001542903ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f2b2a40 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/55/2001542903ac001710ff8a7c6bda0fb8 @@ -0,0 +1,21 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + + public SocketReference(T referent) { + super(referent); + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/55/e05f7dc334ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/55/e05f7dc334ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ba5aaf4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/55/e05f7dc334ac001710ff8a7c6bda0fb8 @@ -0,0 +1,339 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private boolean isRWMaster=true;//与默认值一致 +private boolean islagerRead=false; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + csocket.getInputStream().setLargeRead(islagerRead); + csocket.getInputStream().resetBufMaster(isRWMaster); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + this.isRWMaster=isRead; + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.islagerRead=islarge; +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/56/40e91a0269a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/56/40e91a0269a800171a8482560d609ceb new file mode 100644 index 0000000..fef5062 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/56/40e91a0269a800171a8482560d609ceb @@ -0,0 +1,72 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + entry.getValue().getSocket(); + } + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/56/509c645db5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/56/509c645db5ad0017181ed9113883eda9 new file mode 100644 index 0000000..2449d51 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/56/509c645db5ad0017181ed9113883eda9 @@ -0,0 +1,523 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s0) + { + client.connectNum--; + if(lastAckSequenceNumber/10000!=ackNumber/10000) + { + //修正 + //ackNumber 特别大,则会全部删除,特别小,一个都不会删除 + if(lastAckSequenceNumberthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + } + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/60df03ff04ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/57/60df03ff04ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7461180 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/57/60df03ff04ac001710ff8a7c6bda0fb8 @@ -0,0 +1,33 @@ +/** + * + */ +package judp; + + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + public SocketReference(T referent, long socketID, ReferenceQueue q) { + super(referent,q); + this.socketid=socketID; + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/70fe88816da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/57/70fe88816da800171a8482560d609ceb new file mode 100644 index 0000000..9513601 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/57/70fe88816da800171a8482560d609ceb @@ -0,0 +1,35 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFile.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("127.0.0.1", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/c01e4b7e21ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/57/c01e4b7e21ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..0a6eb23 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/57/c01e4b7e21ac001710ff8a7c6bda0fb8 @@ -0,0 +1,288 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private static final Logger logger=Logger.getLogger(judpSocket.class.getName()); +private PackagetCombin pack=new PackagetCombin(); +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + + +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + flushTime=System.currentTimeMillis(); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/c030fc7309ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/57/c030fc7309ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..0147e71 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/57/c030fc7309ac001710ff8a7c6bda0fb8 @@ -0,0 +1,101 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.util.HashMap; +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + @SuppressWarnings("rawtypes") + private final ReferenceQueue q = new ReferenceQueue(); + private volatile long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private final HashMap,Long> map=new HashMap,Long> (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + map.remove(k); + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + map.put(tmp, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/d0125e1f6da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/57/d0125e1f6da800171a8482560d609ceb new file mode 100644 index 0000000..41b9514 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/57/d0125e1f6da800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * 文件名:TestRecFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpRecviceFile; + +/** + * + * 项目名称:judp + * 类名称:TestRecFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:42 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:42 + * 修改备注: + * @version + * + */ +public class TestRecFile { + + public static void main(String[] args) { + judpRecviceFile rec=new judpRecviceFile("127.0.0.1", 5555, "E:\\Study\\java\\filesudt\\send\\12.rmvb", "E:\\Study\\java\\filesudt\\rec\\1.rmvb"); + rec.start(); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/58/50cfdaa722ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/58/50cfdaa722ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..dc2286d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/58/50cfdaa722ac001710ff8a7c6bda0fb8 @@ -0,0 +1,212 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(client.isClose()) + { + return null; + } + r=client.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; + } + public int read(byte[]data) + { + try { + return client.read(data); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return -1; + } + + /** + * 关闭 + */ + public void close() + { + if(client!=null) + { + if(sumLen==0) + { + //没有发送数据 + //立即关闭 + try { + if(!client.isClose()) + client.shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + //开始缓存 + //SocketManager.getInstance().add(client); + if(!client.isClose()) + client.close(); + } + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/58/80a5207c6fa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/58/80a5207c6fa800171a8482560d609ceb new file mode 100644 index 0000000..e4dde0b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/58/80a5207c6fa800171a8482560d609ceb @@ -0,0 +1,269 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import udt.util.ReceiveBuffer; + +/** + * The UDTInputStream receives data blocks from the {@link UDTSocket} + * as they become available, and places them into an ordered, + * bounded queue (the flow window) for reading by the application + * + * + */ +public class UDTInputStream extends InputStream { + + //the socket owning this inputstream + private final UDTSocket socket; + + private final ReceiveBuffer receiveBuffer; + + //set to 'false' by the receiver when it gets a shutdown signal from the peer + //see the noMoreData() method + private final AtomicBoolean expectMoreData=new AtomicBoolean(true); + + private volatile boolean closed=false; + + private volatile boolean blocking=true; + + private volatile boolean hasData=false;//cd + + + + /** + * create a new {@link UDTInputStream} connected to the given socket + * @param socket - the {@link UDTSocket} + * @throws IOException + */ + public UDTInputStream(UDTSocket socket)throws IOException{ + this.socket=socket; + int capacity=socket!=null? 2 * socket.getSession().getFlowWindowSize() : 128 ; + long initialSequenceNum=socket!=null?socket.getSession().getInitialSequenceNumber():1; + receiveBuffer=new ReceiveBuffer(capacity,initialSequenceNum); + } + + private final byte[]single=new byte[1]; + + @Override + public int read()throws IOException{ + int b=0; + while(b==0) + b=read(single); + + if(b>0){ + return single[0]; + } + else { + return b; + } + } + + private AppData currentChunk=null; + //offset into currentChunk + int offset=0; + long id=-1; + @Override + public int read(byte[]target)throws IOException{ + try{ + int read=0; + updateCurrentChunk(false); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(blocking && read==0); + } + + if(read>0)return read; + if(closed)return -1; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; + //no more data + return -1; + + }catch(Exception ex){ + IOException e= new IOException(); + e.initCause(ex); + throw e; + } + } + + /** + * Reads the next valid chunk of application data from the queue
+ * + * In blocking mode,this method will block until data is available or the socket is closed, + * otherwise it will wait for at most 10 milliseconds. + * + * @throws InterruptedException + */ + private void updateCurrentChunk(boolean block)throws IOException{ + if(currentChunk!=null)return; + + while(true){ + try{ + if(block){ + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); + while (!closed && currentChunk==null){ + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); + } + } + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); + + }catch(InterruptedException ie){ + IOException ex=new IOException(); + ex.initCause(ie); + throw ex; + } + return; + } + } + + /** + * new application data + * @param data + * + */ + protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + return receiveBuffer.offer(new AppData(sequenceNumber,data)); + } + + @Override + public void close()throws IOException{ + if(closed)return; + closed=true; + noMoreData(); + } + + public UDTSocket getSocket(){ + return socket; + } + + /** + * sets the blocking mode + * @param block + */ + public void setBlocking(boolean block){ + this.blocking=block; + } + + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + + /** + * notify the input stream that there is no more data + * @throws IOException + */ + protected void noMoreData()throws IOException{ + expectMoreData.set(false); + } + + /** + * 判断有没有数据进来 + * cd + * @return + */ + public boolean isHasData() + { + return hasData; + } + + /** + * used for storing application data and the associated + * sequence number in the queue in ascending order + */ + public static class AppData implements Comparable{ + final long sequenceNumber; + final byte[] data; + public AppData(long sequenceNumber, byte[]data){ + this.sequenceNumber=sequenceNumber; + this.data=data; + } + + @Override + public int compareTo(AppData o) { + return (int)(sequenceNumber-o.sequenceNumber); + } + + @Override + public String toString(){ + return sequenceNumber+"["+data.length+"]"; + } + + public long getSequenceNumber(){ + return sequenceNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/59/2091b446e0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/59/2091b446e0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..6d8ec44 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/59/2091b446e0ac001716b9ca6d5abb90bc @@ -0,0 +1,148 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5a/10ee44b7a0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/10ee44b7a0ad0017181ed9113883eda9 new file mode 100644 index 0000000..773db69 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/10ee44b7a0ad0017181ed9113883eda9 @@ -0,0 +1,79 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * @author jinyu + * + */ +public class ReadXml { +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Document doc; + try { + doc = (Document) builder.parse(is); + } catch (SAXException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + NodeList list=doc.getElementsByTagName("IP"); + String ip= list.item(0).getTextContent(); + list=doc.getElementsByTagName("Port"); + String port=list.item(0).getTextContent(); + list=doc.getElementsByTagName("Dir"); + String dir=list.item(0).getTextContent(); + String strxml=ip+","+port+","+dir; + return strxml; + } +public String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5a/30d29f9969a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/30d29f9969a800171a8482560d609ceb new file mode 100644 index 0000000..24e8ae2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/30d29f9969a800171a8482560d609ceb @@ -0,0 +1,113 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + sessionHandoff.put(jsocket); + SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ +try { + judpSocket jsocket= sessionHandoff.take(); + return jsocket; +} catch (InterruptedException e) { + logger.info("judpSocket接收中断:"+e.getMessage()); + e.printStackTrace(); +} +return null; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5a/b091bc44e0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/b091bc44e0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..dde6eda --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/b091bc44e0ac001716b9ca6d5abb90bc @@ -0,0 +1,149 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5a/c0e40d3ea0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/c0e40d3ea0ad0017181ed9113883eda9 new file mode 100644 index 0000000..564436a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/c0e40d3ea0ad0017181ed9113883eda9 @@ -0,0 +1,52 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.xml.sax.InputSource; + +/** + * @author jinyu + * + */ +public class ReadXml { +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder=factory.newDocumentBuilder(); + Document doc = (Document) builder.parse(is); + doc.gete +} +public String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5a/c0e9c48ee4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/c0e9c48ee4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..fbac0a2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/c0e9c48ee4ac001716b9ca6d5abb90bc @@ -0,0 +1,220 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5b/b0bdcfc2d7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/5b/b0bdcfc2d7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..85fac30 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5b/b0bdcfc2d7ac001716b9ca6d5abb90bc @@ -0,0 +1,143 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private boolean isRWMaster; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + this.isRWMaster=isRead; + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.isRWMaster=islarge; +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5c/20504804c5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/5c/20504804c5ad0017181ed9113883eda9 new file mode 100644 index 0000000..fcbfe7a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5c/20504804c5ad0017181ed9113883eda9 @@ -0,0 +1,516 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5d/6043da1d1aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/5d/6043da1d1aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..1b2627c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5d/6043da1d1aac001710ff8a7c6bda0fb8 @@ -0,0 +1,74 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + byte[][] result=new byte[num][]; + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + buffer[readPosition]=null;//丢掉数据 + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5e/205e2eb706ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/5e/205e2eb706ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..a0ac084 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5e/205e2eb706ac001710ff8a7c6bda0fb8 @@ -0,0 +1,97 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; + +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + @SuppressWarnings("rawtypes") + private final ReferenceQueue q = new ReferenceQueue(); + private long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5e/30073a3d25ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/5e/30073a3d25ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..b93d76e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5e/30073a3d25ac001710ff8a7c6bda0fb8 @@ -0,0 +1,233 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData= PackagetSub.split(data); + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long startTime=System.currentTimeMillis(); + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-startTime)/1000); + } + + log.info("文件接收速度:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5e/80cf2f975ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/5e/80cf2f975ca800171a8482560d609ceb new file mode 100644 index 0000000..0916152 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5e/80cf2f975ca800171a8482560d609ceb @@ -0,0 +1,232 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + private final int waitClose=10*1000; + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5f/10f8023268a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/5f/10f8023268a800171a8482560d609ceb new file mode 100644 index 0000000..6aa4c17 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5f/10f8023268a800171a8482560d609ceb @@ -0,0 +1,81 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + i=-1;//重新遍历 + index=i; + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5f/d03f8ec3e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/5f/d03f8ec3e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..13eb70a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5f/d03f8ec3e4ac001716b9ca6d5abb90bc @@ -0,0 +1,234 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + if(writeFile(tmp)) + { + ss.close(); + break; + } + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6/40f9d9b9ceac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/6/40f9d9b9ceac001716b9ca6d5abb90bc new file mode 100644 index 0000000..483ab4e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6/40f9d9b9ceac001716b9ca6d5abb90bc @@ -0,0 +1,210 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + if(buffer[insert]==null + } + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/60/0049134464a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/60/0049134464a800171a8482560d609ceb new file mode 100644 index 0000000..f090cbb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/60/0049134464a800171a8482560d609ceb @@ -0,0 +1,45 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + startGC(); + } + + public static synchronized SocketManager getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/60/2023350a64a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/60/2023350a64a800171a8482560d609ceb new file mode 100644 index 0000000..7f0875d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/60/2023350a64a800171a8482560d609ceb @@ -0,0 +1,27 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private ConcurrentHashMap hash=new ConcurrentHashMap(); +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash. + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/60/30e12f8c69a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/60/30e12f8c69a800171a8482560d609ceb new file mode 100644 index 0000000..7ed3973 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/60/30e12f8c69a800171a8482560d609ceb @@ -0,0 +1,99 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;i hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/61/60416b18e5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/61/60416b18e5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..e8b042c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/61/60416b18e5ac001716b9ca6d5abb90bc @@ -0,0 +1,239 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/61/a02c15f303ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/61/a02c15f303ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f46d638 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/61/a02c15f303ac001710ff8a7c6bda0fb8 @@ -0,0 +1,70 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (WeakReference) q.remove()) != null) { + + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/62/d0dc45525ba800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/62/d0dc45525ba800171a8482560d609ceb new file mode 100644 index 0000000..fd9a135 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/62/d0dc45525ba800171a8482560d609ceb @@ -0,0 +1,177 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + public void close() + { + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/63/1027745f23ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/63/1027745f23ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..19c5261 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/63/1027745f23ac001710ff8a7c6bda0fb8 @@ -0,0 +1,232 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData= PackagetSub.split(data); + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + /** + * 接收数据写入文件 + */ + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + else + { + recData(); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/63/40a19ee8ceac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/63/40a19ee8ceac001716b9ca6d5abb90bc new file mode 100644 index 0000000..bf97858 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/63/40a19ee8ceac001716b9ca6d5abb90bc @@ -0,0 +1,220 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + else + { + + } + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/63/f0ff4653cbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/63/f0ff4653cbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..3bf058c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/63/f0ff4653cbac001716b9ca6d5abb90bc @@ -0,0 +1,195 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + //private final HashSet position; + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + //this.position=new HashSet(size); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + /** + * 清除重复检验 + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/64/00f0eed5f6ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/64/00f0eed5f6ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..10c551b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/64/00f0eed5f6ab001710ff8a7c6bda0fb8 @@ -0,0 +1,114 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/64/d0b50df3b4ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/64/d0b50df3b4ad0017181ed9113883eda9 new file mode 100644 index 0000000..97e82d9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/64/d0b50df3b4ad0017181ed9113883eda9 @@ -0,0 +1,187 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.SocketException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.SequenceNumber; + +/** + * Client side of a client-server UDT connection. + * Once established, the session provides a valid {@link UDTSocket}. + */ +public class ClientSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private UDPEndPoint endPoint; + public int connectNum=0; + public ClientSession(UDPEndPoint endPoint, Destination dest)throws SocketException{ + super("ClientSession localPort="+endPoint.getLocalPort(),dest); + this.endPoint=endPoint; + logger.info("Created "+toString()); + } + + /** + * send connection handshake until a reply from server is received + * TODO check for timeout + * @throws InterruptedException + * @throws IOException + */ + + public void connect() throws InterruptedException,IOException{ + int n=0; + + while(getState()!=ready){ + + sendHandShake(); + if(getState()==invalid)throw new IOException("Can't connect!"); + n++; + if(getState()!=ready)Thread.sleep(500); + } + + cc.init(); + logger.info("Connected, "+n+" handshake packets sent"); + } + + @Override + public void received(UDTPacket packet, Destination peer) { + + lastPacket=packet; + + if (packet instanceof ConnectionHandshake) { + ConnectionHandshake hs=(ConnectionHandshake)packet; + + logger.info("Received connection handshake from "+peer+"\n"+hs); + + if (getState()!=ready) { + if(hs.getConnectionType()==1){ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + sendConfirmation(hs); + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + else{ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + setState(ready); + Thread.sleep(50); + this.setInitialSequenceNumber(hs.getInitialSeqNo());//cd 必须重置 + System.out.println("初始序列置回2:"+this.getInitialSequenceNumber()); + socket=new UDTSocket(endPoint,this); + + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + } + } + + if(getState() == ready) { + + if(packet instanceof Shutdown){ + setState(shutdown); + active=false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + active = true; + try{ + if(packet.forSender()){ + socket.getSender().receive(lastPacket); + }else{ + socket.getReceiver().receive(lastPacket); + } + }catch(Exception ex){ + //session is invalid + logger.log(Level.SEVERE,"Error in "+toString(),ex); + setState(invalid); + } + return; + } + } + + + //handshake for connect + protected void sendHandShake()throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(ConnectionHandshake.CONNECTION_TYPE_REGULAR); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + long initialSequenceNo=SequenceNumber.random(); + setInitialSequenceNumber(initialSequenceNo); + handshake.setInitialSeqNo(initialSequenceNo); + handshake.setPacketSize(getDatagramSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending "+handshake); + endPoint.doSend(handshake); + } + + //2nd handshake for connect + protected void sendConfirmation(ConnectionHandshake hs)throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(-1); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + handshake.setInitialSeqNo(hs.getInitialSeqNo()); + handshake.setPacketSize(hs.getPacketSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending confirmation "+handshake); + endPoint.doSend(handshake); + } + + + public UDTPacket getLastPkt(){ + return lastPacket; + } + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/65/20253f0eb3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/65/20253f0eb3ad0017181ed9113883eda9 new file mode 100644 index 0000000..1c4526c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/65/20253f0eb3ad0017181ed9113883eda9 @@ -0,0 +1,503 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/65/50bfc894a6ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/65/50bfc894a6ad0017181ed9113883eda9 new file mode 100644 index 0000000..daaf7cb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/65/50bfc894a6ad0017181ed9113883eda9 @@ -0,0 +1,52 @@ +/** + * + */ +package net.File; + +import java.io.File; +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + + ReadXml rd=new ReadXml(); + String xml= rd.readXml(ReadXml.getPath()+"/config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + SendFiles send=new SendFiles(config[0], Integer.valueOf(config[1])); + FilesWatch watch=new FilesWatch(); + String dir=config[2]; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/65/c0b5f764b9ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/65/c0b5f764b9ad0017181ed9113883eda9 new file mode 100644 index 0000000..df6ad44 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/65/c0b5f764b9ad0017181ed9113883eda9 @@ -0,0 +1,356 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.PacketFactory; +import udt.util.UDTThreadFactory; + +/** + * the UDPEndpoint takes care of sending and receiving UDP network packets, + * dispatching them to the correct {@link UDTSession} + */ +public class UDPEndPoint { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private final int port; + + private final DatagramSocket dgSocket; + + //active sessions keyed by socket ID + private final Mapsessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest);//cd + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&stopped) + { + //cd + //已经正常关闭 + } + else + { + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + } + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/65/d0bc506103ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/65/d0bc506103ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c0c594c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/65/d0bc506103ac001710ff8a7c6bda0fb8 @@ -0,0 +1,24 @@ +/** + * + */ +package judp; + + +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + private final long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/65/e0d96e5a1eac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/65/e0d96e5a1eac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ce762a1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/65/e0d96e5a1eac001710ff8a7c6bda0fb8 @@ -0,0 +1,28 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public DataStruct addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + struct.addData(data); + return struct; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/66/10f59fb9a0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/66/10f59fb9a0ad0017181ed9113883eda9 new file mode 100644 index 0000000..e9cfdb4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/66/10f59fb9a0ad0017181ed9113883eda9 @@ -0,0 +1,79 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * @author jinyu + * + */ +public class ReadXml { +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Document doc = null; + try { + doc = (Document) builder.parse(is); + } catch (SAXException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + NodeList list=doc.getElementsByTagName("IP"); + String ip= list.item(0).getTextContent(); + list=doc.getElementsByTagName("Port"); + String port=list.item(0).getTextContent(); + list=doc.getElementsByTagName("Dir"); + String dir=list.item(0).getTextContent(); + String strxml=ip+","+port+","+dir; + return strxml; + } +public String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/66/704245e5e1ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/66/704245e5e1ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..b82e88d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/66/704245e5e1ac001716b9ca6d5abb90bc @@ -0,0 +1,148 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + log.info("发送:"+f.getName()+","+); + } + long endTime=System.currentTimeMillis(); + client.close(); + dis.close(); + long speed=fLen/((endTime-startTime)/1000); + log.info("发送完成:"+f.getName()+",平均速度(M/S):"+speed/1024/1024); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/66/804c48ac2bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/66/804c48ac2bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..d60160c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/66/804c48ac2bac001710ff8a7c6bda0fb8 @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int sumNum=0; +private volatile int sumLen=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} + +/** + * 整理数据 + * @return + */ +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-lastTime)/1000); + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/67/1081b1f8b5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/67/1081b1f8b5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..721e9fa --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/67/1081b1f8b5ac001716b9ca6d5abb90bc @@ -0,0 +1,191 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.KeepAlive; +import udt.packets.Shutdown; + +/** + * server side session in client-server mode + */ +public class ServerSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ServerSession.class.getName()); + + private final UDPEndPoint endPoint; + + //last received packet (for testing purposes) + private UDTPacket lastPacket; + + + public ServerSession(DatagramPacket dp, UDPEndPoint endPoint)throws SocketException,UnknownHostException{ + super("ServerSession localPort="+endPoint.getLocalPort()+" peer="+dp.getAddress()+":"+dp.getPort(),new Destination(dp.getAddress(),dp.getPort())); + this.endPoint=endPoint; + logger.info("Created "+toString()+" talking to "+dp.getAddress()+":"+dp.getPort()); + } + + int n_handshake=0; + + @Override + public void received(UDTPacket packet, Destination peer){ + lastPacket=packet; + + if(packet instanceof ConnectionHandshake) { + ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; + logger.info("Received "+connectionHandshake); + + if (getState()<=ready){ + destination.setSocketID(connectionHandshake.getSocketID()); + + if(getState()<=handshaking){ + setState(handshaking); + } + try{ + handleHandShake(connectionHandshake); + n_handshake++; + try{ + setState(ready); + socket=new UDTSocket(endPoint, this); + cc.init(); + }catch(Exception uhe){ + //session is invalid + logger.log(Level.SEVERE,"",uhe); + setState(invalid); + } + }catch(IOException ex){ + //session invalid + logger.log(Level.WARNING,"Error processing ConnectionHandshake",ex); + setState(invalid); + } + return; + } + + }else if(packet instanceof KeepAlive) { + socket.getReceiver().resetEXPTimer(); + active = true; + return; + } + + if(getState()== ready) { + active = true; + + if (packet instanceof KeepAlive) { + //nothing to do here + return; + }else if (packet instanceof Shutdown) { + try{ + socket.getReceiver().stop(); + }catch(IOException ex){ + logger.log(Level.WARNING,"",ex); + } + setState(shutdown); + System.out.println("SHUTDOWN ***"); + active = false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + + else{ + try{ + logger.info("DataPacket:"+packet.getPacketSequenceNumber()); + if(packet.forSender()){ + socket.getSender().receive(packet); + }else{ + socket.getReceiver().receive(packet); + } + }catch(Exception ex){ + //session invalid + logger.log(Level.SEVERE,"",ex); + setState(invalid); + } + } + return; + + } + + + } + + /** + * for testing use only + */ + UDTPacket getLastPacket(){ + return lastPacket; + } + + /** + * handle the connection handshake:
+ *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/67/60dc22d413ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/67/60dc22d413ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..e0ebf3f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/67/60dc22d413ac001710ff8a7c6bda0fb8 @@ -0,0 +1,28 @@ +package Test; + +import java.util.concurrent.TimeUnit; + +import judp.judpClient; + +public class TestClient { + + public static void main(String[] args) { + long num=0; + while(true) + { + judpClient client=new judpClient(); + client.connect("192.168.30.128", 5555); + byte[]data=("hello word "+num).getBytes(); + client.sendData(data); + client.close(); + try { + System.out.println("等待"); + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/67/80be36cff8ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/67/80be36cff8ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..b64eea9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/67/80be36cff8ab001710ff8a7c6bda0fb8 @@ -0,0 +1,351 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.PacketFactory; +import udt.util.UDTThreadFactory; + +/** + * the UDPEndpoint takes care of sending and receiving UDP network packets, + * dispatching them to the correct {@link UDTSession} + */ +public class UDPEndPoint { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private final int port; + + private final DatagramSocket dgSocket; + + //active sessions keyed by socket ID + private final Mapsessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&) + { + //已经 + } + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/67/c071fbe65ea800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/67/c071fbe65ea800171a8482560d609ceb new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/67/d0d5236bf4ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/67/d0d5236bf4ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..a3b5422 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/67/d0d5236bf4ab001710ff8a7c6bda0fb8 @@ -0,0 +1,27 @@ +package Test; + +import java.util.concurrent.TimeUnit; + +import judp.judpClient; + +public class TestClient { + + public static void main(String[] args) { + while(true) + { + judpClient client=new judpClient(); + client.connect("127.0.0.1", 5555); + byte[]data=("hello word "+System.currentTimeMillis()).getBytes(); + client.sendData(data); + client.close(); + try { + System.out.println("等待"); + TimeUnit.SECONDS.sleep(40); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/69/b06da8a2d8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/69/b06da8a2d8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..57f26ad --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/69/b06da8a2d8ac001716b9ca6d5abb90bc @@ -0,0 +1,152 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private boolean isRWMaster=true;//与默认值一致 +private boolean islagerRead=false; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + try { + csocket.getInputStream().setLargeRead(islagerRead); + csocket.getInputStream().resetBufMaster(isRWMaster); + } catch (IOException e) { + e.printStackTrace(); + } + + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * 设置大数据读取才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + this.isRWMaster=isRead; + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.islagerRead=islarge; +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/69/d0e5e1f3a0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/69/d0e5e1f3a0ad0017181ed9113883eda9 new file mode 100644 index 0000000..faccbc2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/69/d0e5e1f3a0ad0017181ed9113883eda9 @@ -0,0 +1,45 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + ReadXml rd=new ReadXml(); + rd.readXml("config.xml"); + SendFiles send=new SendFiles("192.168.30.128", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6a/40965eabcfac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/6a/40965eabcfac001716b9ca6d5abb90bc new file mode 100644 index 0000000..03c11f3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6a/40965eabcfac001716b9ca6d5abb90bc @@ -0,0 +1,232 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 + if(highestReadSequenceNumber+1100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + TimeUnit.SECONDS.sleep(1); + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6e/40913b1af8ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/40913b1af8ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..86b3655 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/40913b1af8ab001710ff8a7c6bda0fb8 @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.logging.Logger; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +private static final Logger logger=Logger.getLogger(judpGroupSocket.class.getName()); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取有数据socket + * 并且移除其它无用socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + index=i; + i=-1;//重新遍历 + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +/** + * 清除所有socket + */ +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6e/c0a030dfdfac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/c0a030dfdfac001716b9ca6d5abb90bc new file mode 100644 index 0000000..b176735 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/c0a030dfdfac001716b9ca6d5abb90bc @@ -0,0 +1,187 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long startTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-startTime)/1000); + } + catch(Exception ex) + { + + } + log.info("文件接收速度:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6e/d0f5ffe8f7ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/d0f5ffe8f7ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..d411386 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/d0f5ffe8f7ab001710ff8a7c6bda0fb8 @@ -0,0 +1,87 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取有数据socket + * 并且移除其它无用socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + index=i; + i=-1;//重新遍历 + + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +/** + * 清除所有socket + */ +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6f/a0409b8eb3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/6f/a0409b8eb3ad0017181ed9113883eda9 new file mode 100644 index 0000000..c920737 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6f/a0409b8eb3ad0017181ed9113883eda9 @@ -0,0 +1,514 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + } + + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6f/c03e69c56da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/6f/c03e69c56da800171a8482560d609ceb new file mode 100644 index 0000000..9361825 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6f/c03e69c56da800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * 文件名:TestRecFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpRecviceFile; + +/** + * + * 项目名称:judp + * 类名称:TestRecFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:42 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:42 + * 修改备注: + * @version + * + */ +public class TestRecFiles { + + public static void main(String[] args) { + judpRecviceFile rec=new judpRecviceFile("127.0.0.1", 5555, "E:\\Study\\java\\filesudt\\send\\12.rmvb", "E:\\Study\\java\\filesudt\\rec\\1.rmvb"); + rec.start(); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7/509a29f366a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/7/509a29f366a800171a8482560d609ceb new file mode 100644 index 0000000..5f690c2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7/509a29f366a800171a8482560d609ceb @@ -0,0 +1,54 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + for( int i = 0 ; i < list.size() ; i++) { + try { + if(list.get(i).getInputStream().isHasData()) + { + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7/a0002b2d5ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/7/a0002b2d5ca800171a8482560d609ceb new file mode 100644 index 0000000..2f70404 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7/a0002b2d5ca800171a8482560d609ceb @@ -0,0 +1,202 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + + } + } + + } + + }); + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7/d084703024ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7/d084703024ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..9c4ef51 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7/d084703024ac001710ff8a7c6bda0fb8 @@ -0,0 +1,233 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData= PackagetSub.split(data); + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/70/907af0871eac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/70/907af0871eac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ce762a1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/70/907af0871eac001710ff8a7c6bda0fb8 @@ -0,0 +1,28 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public DataStruct addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + struct.addData(data); + return struct; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/71/3084b6db9aad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/71/3084b6db9aad0017181ed9113883eda9 new file mode 100644 index 0000000..1db08e7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/71/3084b6db9aad0017181ed9113883eda9 @@ -0,0 +1,43 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + SendFiles send=new SendFiles("127.0.0.1", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/71/5038a5acd5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/71/5038a5acd5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..668bd85 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/71/5038a5acd5ac001716b9ca6d5abb90bc @@ -0,0 +1,264 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/71/604351d567a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/71/604351d567a800171a8482560d609ceb new file mode 100644 index 0000000..09568a3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/71/604351d567a800171a8482560d609ceb @@ -0,0 +1,70 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + i=-1;//重新遍历 + index=i; + } + } + else + { + // + if(i==index) + { + continue; + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/71/60903e2466a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/71/60903e2466a800171a8482560d609ceb new file mode 100644 index 0000000..bb5667c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/71/60903e2466a800171a8482560d609ceb @@ -0,0 +1,45 @@ +/** + * + */ +package judp; + +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + for( int i = 0 ; i < list.size() ; i++) { + if(list.get(i).getInputStream().isHasData()) + { + return list.get(i); + } + } + return null; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/71/80add8d6d7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/71/80add8d6d7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..cef47cd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/71/80add8d6d7ac001716b9ca6d5abb90bc @@ -0,0 +1,143 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private boolean isRWMaster=true;//与默认值一致 +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + this.isRWMaster=isRead; + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.isRWMaster=islarge; +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/71/b04f3e4167a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/71/b04f3e4167a800171a8482560d609ceb new file mode 100644 index 0000000..c639eca --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/71/b04f3e4167a800171a8482560d609ceb @@ -0,0 +1,66 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + UDTSocket find=null; + int index=0; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(find==null) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关闭 + find=list.get(i); + i=-1;//重新遍历 + } + } + else + { + // + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/72/10921d306fa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/72/10921d306fa800171a8482560d609ceb new file mode 100644 index 0000000..304fccf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/72/10921d306fa800171a8482560d609ceb @@ -0,0 +1,115 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +// private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + int num=0; + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + num++; + // + if(!list.isEmpty()) + { + for(int i=0;i list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public judpGroupSocket getSocket() +{ + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/72/f02fa8b892ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/72/f02fa8b892ad0017181ed9113883eda9 new file mode 100644 index 0000000..476638b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/72/f02fa8b892ad0017181ed9113883eda9 @@ -0,0 +1,503 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + + lastAckSequenceNumber=ackNumber; + } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/73/00abaea82bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/73/00abaea82bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..cefffa2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/73/00abaea82bac001710ff8a7c6bda0fb8 @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} + +/** + * 整理数据 + * @return + */ +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + TimeUnit.SECONDS.sleep(1); + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/74/3091ac6c7fad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/74/3091ac6c7fad0017181ed9113883eda9 new file mode 100644 index 0000000..b61d81d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/74/3091ac6c7fad0017181ed9113883eda9 @@ -0,0 +1,191 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.KeepAlive; +import udt.packets.Shutdown; + +/** + * server side session in client-server mode + */ +public class ServerSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ServerSession.class.getName()); + + private final UDPEndPoint endPoint; + + //last received packet (for testing purposes) + private UDTPacket lastPacket; + + + public ServerSession(DatagramPacket dp, UDPEndPoint endPoint)throws SocketException,UnknownHostException{ + super("ServerSession localPort="+endPoint.getLocalPort()+" peer="+dp.getAddress()+":"+dp.getPort(),new Destination(dp.getAddress(),dp.getPort())); + this.endPoint=endPoint; + logger.info("Created "+toString()+" talking to "+dp.getAddress()+":"+dp.getPort()); + } + + int n_handshake=0; + + @Override + public void received(UDTPacket packet, Destination peer){ + lastPacket=packet; + + if(packet instanceof ConnectionHandshake) { + ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; + logger.info("Received "+connectionHandshake); + + if (getState()<=ready){ + destination.setSocketID(connectionHandshake.getSocketID()); + + if(getState()<=handshaking){ + setState(handshaking); + } + try{ + handleHandShake(connectionHandshake); + n_handshake++; + try{ + setState(ready); + socket=new UDTSocket(endPoint, this); + cc.init(); + }catch(Exception uhe){ + //session is invalid + logger.log(Level.SEVERE,"",uhe); + setState(invalid); + } + }catch(IOException ex){ + //session invalid + logger.log(Level.WARNING,"Error processing ConnectionHandshake",ex); + setState(invalid); + } + return; + } + + }else if(packet instanceof KeepAlive) { + socket.getReceiver().resetEXPTimer(); + active = true; + return; + } + + if(getState()== ready) { + active = true; + + if (packet instanceof KeepAlive) { + //nothing to do here + return; + }else if (packet instanceof Shutdown) { + try{ + socket.getReceiver().stop(); + }catch(IOException ex){ + logger.log(Level.WARNING,"",ex); + } + setState(shutdown); + System.out.println("SHUTDOWN ***"); + active = false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + + else{ + try{ + + if(packet.forSender()){ + socket.getSender().receive(packet); + }else{ + socket.getReceiver().receive(packet); + } + }catch(Exception ex){ + //session invalid + logger.log(Level.SEVERE,"",ex); + setState(invalid); + } + } + return; + + } + + + } + + /** + * for testing use only + */ + UDTPacket getLastPacket(){ + return lastPacket; + } + + /** + * handle the connection handshake:
+ *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/74/70995f1f6da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/74/70995f1f6da800171a8482560d609ceb new file mode 100644 index 0000000..9361825 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/74/70995f1f6da800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * 文件名:TestRecFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpRecviceFile; + +/** + * + * 项目名称:judp + * 类名称:TestRecFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:42 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:42 + * 修改备注: + * @version + * + */ +public class TestRecFiles { + + public static void main(String[] args) { + judpRecviceFile rec=new judpRecviceFile("127.0.0.1", 5555, "E:\\Study\\java\\filesudt\\send\\12.rmvb", "E:\\Study\\java\\filesudt\\rec\\1.rmvb"); + rec.start(); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/74/a0ba2744b2ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/74/a0ba2744b2ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..bb7eedd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/74/a0ba2744b2ac001716b9ca6d5abb90bc @@ -0,0 +1,191 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.KeepAlive; +import udt.packets.Shutdown; + +/** + * server side session in client-server mode + */ +public class ServerSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ServerSession.class.getName()); + + private final UDPEndPoint endPoint; + + //last received packet (for testing purposes) + private UDTPacket lastPacket; + + + public ServerSession(DatagramPacket dp, UDPEndPoint endPoint)throws SocketException,UnknownHostException{ + super("ServerSession localPort="+endPoint.getLocalPort()+" peer="+dp.getAddress()+":"+dp.getPort(),new Destination(dp.getAddress(),dp.getPort())); + this.endPoint=endPoint; + logger.info("Created "+toString()+" talking to "+dp.getAddress()+":"+dp.getPort()); + } + + int n_handshake=0; + + @Override + public void received(UDTPacket packet, Destination peer){ + lastPacket=packet; + + if(packet instanceof ConnectionHandshake) { + ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; + logger.info("Received "+connectionHandshake); + + if (getState()<=ready){ + destination.setSocketID(connectionHandshake.getSocketID()); + + if(getState()<=handshaking){ + setState(handshaking); + } + try{ + handleHandShake(connectionHandshake); + n_handshake++; + try{ + setState(ready); + socket=new UDTSocket(endPoint, this); + cc.init(); + }catch(Exception uhe){ + //session is invalid + logger.log(Level.SEVERE,"",uhe); + setState(invalid); + } + }catch(IOException ex){ + //session invalid + logger.log(Level.WARNING,"Error processing ConnectionHandshake",ex); + setState(invalid); + } + return; + } + + }else if(packet instanceof KeepAlive) { + socket.getReceiver().resetEXPTimer(); + active = true; + return; + } + + if(getState()== ready) { + active = true; + + if (packet instanceof KeepAlive) { + //nothing to do here + return; + }else if (packet instanceof Shutdown) { + try{ + socket.getReceiver().stop(); + }catch(IOException ex){ + logger.log(Level.WARNING,"",ex); + } + setState(shutdown); + System.out.println("SHUTDOWN ***"); + active = false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + + else{ + try{ + logger.info("DataPacket:"+p.getPacketSequenceNumber()); + if(packet.forSender()){ + socket.getSender().receive(packet); + }else{ + socket.getReceiver().receive(packet); + } + }catch(Exception ex){ + //session invalid + logger.log(Level.SEVERE,"",ex); + setState(invalid); + } + } + return; + + } + + + } + + /** + * for testing use only + */ + UDTPacket getLastPacket(){ + return lastPacket; + } + + /** + * handle the connection handshake:
+ *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/74/b065917426ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/74/b065917426ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..db39f83 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/74/b065917426ac001710ff8a7c6bda0fb8 @@ -0,0 +1,87 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;ihandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + logger.info("haveNewData:失败"); + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + logger.info("largestReceivedSeqNumber:"+largestReceivedSeqNumber); + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/75/a0430dbae1ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/75/a0430dbae1ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..778d49f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/75/a0430dbae1ac001716b9ca6d5abb90bc @@ -0,0 +1,149 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + + } + + } + long endTime=System.currentTimeMillis(); + client.close(); + dis.close(); + long speed=fLen/((endTime-startTime)/1000); + log.info("发送完成:"+f.getName()+",平均速度(M/S):"+speed/1024/1024); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/75/b0a223eb03ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/75/b0a223eb03ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..532b638 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/75/b0a223eb03ac001710ff8a7c6bda0fb8 @@ -0,0 +1,70 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取;也要外部快速读取 + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + // cd + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + + if(readPosition==size) + {readPosition=0; + if(this.islagerRead) + { + //cd + clearDeHash(this.size-leftNum); + } + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } + + /** + * 设置大数据读取 + * @param islarge + */ + public void setlargeRead(boolean islarge) + { + this.islagerRead=islarge; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/77/403c36a21aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/77/403c36a21aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..eed32b4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/77/403c36a21aac001710ff8a7c6bda0fb8 @@ -0,0 +1,12 @@ +/** + * + */ +package judp; + +/** + * @author jinyu + * + */ +public class DataStruct { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/78/10e15310c3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/78/10e15310c3ad0017181ed9113883eda9 new file mode 100644 index 0000000..8d9a372 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/78/10e15310c3ad0017181ed9113883eda9 @@ -0,0 +1,525 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s0) + { + + if(lastAckSequenceNumber/10000!=ackNumber/10000) + { + client.connectNum--; + logger.info("修正lastAckSequenceNumber:"+ackNumber); + //修正 + //ackNumber 特别大,则会全部删除,特别小,一个都不会删除 + if(lastAckSequenceNumberthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + } + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/78/8067edbee4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/78/8067edbee4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..fd792ee --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/78/8067edbee4ac001716b9ca6d5abb90bc @@ -0,0 +1,229 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + TimeUnit.MILLISECONDS.sleep(100); + } + if(writeFile(tmp)) + { + ss.close(); + break; + } + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/78/9086b899d8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/78/9086b899d8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..22b9ccb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/78/9086b899d8ac001716b9ca6d5abb90bc @@ -0,0 +1,152 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private boolean isRWMaster=true;//与默认值一致 +private boolean islagerRead=false; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + try { + csocket.getInputStream().setLargeRead(islagerRead); + csocket.getInputStream().resetBufMaster(isRWMaster); + } catch (IOException e) { + e.printStackTrace(); + } + + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + this.isRWMaster=isRead; + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.islagerRead=islarge; +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/78/b07ba83069a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/78/b07ba83069a800171a8482560d609ceb new file mode 100644 index 0000000..39f7363 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/78/b07ba83069a800171a8482560d609ceb @@ -0,0 +1,91 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7a/60f5446d26ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7a/60f5446d26ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ca3ae6b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7a/60f5446d26ac001710ff8a7c6bda0fb8 @@ -0,0 +1,87 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (SocketReference) q.remove()) != null) { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7c/00baf1751bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7c/00baf1751bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..fe052ed --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7c/00baf1751bac001710ff8a7c6bda0fb8 @@ -0,0 +1,14 @@ +/** + * + */ +package judp; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[] data; +public long id; +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7c/708d70c31aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7c/708d70c31aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7c/f009da97d5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/7c/f009da97d5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..662c22b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7c/f009da97d5ac001716b9ca6d5abb90bc @@ -0,0 +1,255 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7d/50c2175e68a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/50c2175e68a800171a8482560d609ceb new file mode 100644 index 0000000..8355492 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/50c2175e68a800171a8482560d609ceb @@ -0,0 +1,78 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + i=-1;//重新遍历 + index=i; + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7d/50df241c27ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/50df241c27ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..00bab17 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/50df241c27ac001710ff8a7c6bda0fb8 @@ -0,0 +1,328 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=PackagetSub.split(data); + for(int i=0;ihandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7d/a00a34b931ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/a00a34b931ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ef16d27 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/a00a34b931ac001710ff8a7c6bda0fb8 @@ -0,0 +1,338 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(getCloseState) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i0){ + return single[0]; + } + else { + return b; + } + } + + private AppData currentChunk=null; + //offset into currentChunk + int offset=0; + long id=-1; + @Override + public int read(byte[]target)throws IOException{ + try{ + int read=0; + updateCurrentChunk(false); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(blocking && read==0); + } + + if(read>0)return read; + if(closed)return -1; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; + //no more data + return -1; + + }catch(Exception ex){ + IOException e= new IOException(); + e.initCause(ex); + throw e; + } + } + + /** + * Reads the next valid chunk of application data from the queue
+ * + * In blocking mode,this method will block until data is available or the socket is closed, + * otherwise it will wait for at most 10 milliseconds. + * + * @throws InterruptedException + */ + private void updateCurrentChunk(boolean block)throws IOException{ + if(currentChunk!=null)return; + + while(true){ + try{ + if(block){ + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); + while (!closed && currentChunk==null){ + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); + } + } + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); + + }catch(InterruptedException ie){ + IOException ex=new IOException(); + ex.initCause(ie); + throw ex; + } + return; + } + } + + /** + * new application data + * @param data + * + */ + protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + hasData=true; + return receiveBuffer.offer(new AppData(sequenceNumber,data)); + } + + @Override + public void close()throws IOException{ + if(closed)return; + closed=true; + noMoreData(); + } + + public UDTSocket getSocket(){ + return socket; + } + + /** + * sets the blocking mode + * @param block + */ + public void setBlocking(boolean block){ + this.blocking=block; + } + + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + + /** + * notify the input stream that there is no more data + * @throws IOException + */ + protected void noMoreData()throws IOException{ + expectMoreData.set(false); + } + + /** + * 判断有没有数据进来 + * cd + * @return + */ + public boolean isHasData() + { + return hasData; + } + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + receiveBuffer.setBufMaster(isRead); + + } + + /** + * 设置大数据读取 + * 默认 false + * @param islarge + */ + public void setLargeRead(boolean islarge) + { + receiveBuffer.setLargeRead(islarge); + } + /** + * used for storing application data and the associated + * sequence number in the queue in ascending order + */ + public static class AppData implements Comparable{ + final long sequenceNumber; + final byte[] data; + public AppData(long sequenceNumber, byte[]data){ + this.sequenceNumber=sequenceNumber; + this.data=data; + } + + @Override + public int compareTo(AppData o) { + return (int)(sequenceNumber-o.sequenceNumber); + } + + @Override + public String toString(){ + return sequenceNumber+"["+data.length+"]"; + } + + public long getSequenceNumber(){ + return sequenceNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7d/d043da1809ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/d043da1809ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..5ae9543 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/d043da1809ac001710ff8a7c6bda0fb8 @@ -0,0 +1,98 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; + +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + @SuppressWarnings("rawtypes") + private final ReferenceQueue q = new ReferenceQueue(); + private volatile long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7d/f014ead31aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/f014ead31aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..8d1ee8a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/f014ead31aac001710ff8a7c6bda0fb8 @@ -0,0 +1,12 @@ +/** + * + */ +package judp; + +/** + * @author jinyu + * + */ +public class PackagetCombin { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7e/006d75ddffab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/006d75ddffab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..6fd43fa --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/006d75ddffab001710ff8a7c6bda0fb8 @@ -0,0 +1,79 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + + + } + private void startThread() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + WeakReference objsocket=queue.take(); + if(objsocket.get()!=null) + { + judpSocket socket=objsocket.get(); + if(socket.getCloseState()) + { + if(endPoint!=null) + { + endPoint.removeSession(socket.getSocketID()); + } + } + } + + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7e/401863511cac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/401863511cac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..3b71a22 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/401863511cac001710ff8a7c6bda0fb8 @@ -0,0 +1,38 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer; +public long id; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + +} +public boolean addData(byte[]data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + int index=buf.getInt(); + dataLen=buf.getInt(); + byte[] tmp=new byte[buf.limit()-buf.position()]; + buf.get(tmp); + buffer[index]=tmp; + +} + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7e/b067998b05ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/b067998b05ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..d9640f6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/b067998b05ac001710ff8a7c6bda0fb8 @@ -0,0 +1,93 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7f/3056569822ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7f/3056569822ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7e284f6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7f/3056569822ac001710ff8a7c6bda0fb8 @@ -0,0 +1,208 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(client.isClose()) + { + return null; + } + r=client.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; + } + public int read(byte[]data) + { + try { + return client.read(data); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return -1; + } + public void close() + { + if(client!=null) + { + if(sumLen==0) + { + //没有发送数据 + //立即关闭 + try { + if(!client.isClose()) + client.shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + //开始缓存 + //SocketManager.getInstance().add(client); + if(!client.isClose()) + client.close(); + } + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7f/40c53669d8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/7f/40c53669d8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..17670bd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7f/40c53669d8ac001716b9ca6d5abb90bc @@ -0,0 +1,363 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + + + } + private void startThread() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + WeakReference objsocket=queue.take(); + if(objsocket.get()!=null) + { + judpSocket socket=objsocket.get(); + if(socket.getCloseState()) + { + socket. + } + } + + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7f/b07dd0961bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/7f/b07dd0961bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ff17ea3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7f/b07dd0961bac001710ff8a7c6bda0fb8 @@ -0,0 +1,14 @@ +/** + * + */ +package judp; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] data; +public long id; +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/80/105d7f665ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/80/105d7f665ca800171a8482560d609ceb new file mode 100644 index 0000000..79ba998 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/80/105d7f665ca800171a8482560d609ceb @@ -0,0 +1,223 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/80/d030786d1aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/80/d030786d1aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..63f3244 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/80/d030786d1aac001710ff8a7c6bda0fb8 @@ -0,0 +1,76 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i0){ + int len=Math.min(bb.remaining(),chunksize); + byte[]chunk=new byte[len]; + bb.get(chunk); + DataPacket packet=new DataPacket(); + seqNo=sender.getNextSequenceNumber(); + packet.setPacketSequenceNumber(seqNo); + packet.setSession(session); + packet.setDestinationID(session.getDestination().getSocketID()); + packet.setData(chunk); + + //put the packet into the send queue + if(!sender.sendUdtPacket(packet, timeout, units)){ + throw new IOException("Queue full"); + } + + } + if(length>0)active=true; + + } + /** + * will block until the outstanding packets have really been sent out + * and acknowledged + */ + protected void flush() throws InterruptedException{ + if(!active)return; + final long seqNo=sender.getCurrentSequenceNumber(); + if(seqNo<0)throw new IllegalStateException(); + while(!sender.isSentOut(seqNo)){ + Thread.sleep(5); + } + if(seqNo>-1){ + //wait until data has been sent out and acknowledged + while(active && !sender.haveAcknowledgementFor(seqNo)){ + sender.waitForAck(seqNo); + } + } + //TODO need to check if we can pause the sender... + //sender.pause(); + } + + //writes and wait for ack + protected void doWriteBlocking(byte[]data)throws IOException, InterruptedException{ + doWrite(data); + System.out.println("flush"); + flush(); + System.out.println("flush out"); + } + + /** + * close the connection + * @throws IOException + */ + public void close()throws IOException{ + if(inputStream!=null)inputStream.close(); + if(outputStream!=null)outputStream.close(); + active=false; + close=true; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/81/500e2b00d6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/81/500e2b00d6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..8a8a7be --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/81/500e2b00d6ac001716b9ca6d5abb90bc @@ -0,0 +1,273 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/82/0096696f19ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/82/0096696f19ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..05bd6a2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/82/0096696f19ac001710ff8a7c6bda0fb8 @@ -0,0 +1,14 @@ +/** + * + */ +package judp; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong subid=new AtomicLong(0); + public static int dataSzie=1472; + public byte[][] split(byte[]data) +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/82/209d88b969a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/82/209d88b969a800171a8482560d609ceb new file mode 100644 index 0000000..68eb196 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/82/209d88b969a800171a8482560d609ceb @@ -0,0 +1,114 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ +try { + SocketControls.getInstance().getSocket(); + judpSocket jsocket= sessionHandoff.take(); + return jsocket; +} catch (InterruptedException e) { + logger.info("judpSocket接收中断:"+e.getMessage()); + e.printStackTrace(); +} +return null; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/82/50bd4a31d6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/82/50bd4a31d6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..dfedccd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/82/50bd4a31d6ac001716b9ca6d5abb90bc @@ -0,0 +1,279 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + // cd + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + + if(readPosition==size) + {readPosition=0; + if(this.islagerRead) + { + //cd + clearDeHash(this.size-leftNum); + } + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/82/7042778204ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/82/7042778204ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f72cd53 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/82/7042778204ac001710ff8a7c6bda0fb8 @@ -0,0 +1,86 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + + } + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/82/801757f229ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/82/801757f229ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..2e2ea88 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/82/801757f229ac001710ff8a7c6bda0fb8 @@ -0,0 +1,99 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i0){ + int len=Math.min(bb.remaining(),chunksize); + byte[]chunk=new byte[len]; + bb.get(chunk); + DataPacket packet=new DataPacket(); + seqNo=sender.getNextSequenceNumber(); + packet.setPacketSequenceNumber(seqNo); + packet.setSession(session); + packet.setDestinationID(session.getDestination().getSocketID()); + packet.setData(chunk); + System.out.println("sender sendUdtPacket1"); + //put the packet into the send queue + if(!sender.sendUdtPacket(packet, timeout, units)){ + throw new IOException("Queue full"); + } + System.out.println("sender sendUdtPacket2"); + } + if(length>0)active=true; + } + /** + * will block until the outstanding packets have really been sent out + * and acknowledged + */ + protected void flush() throws InterruptedException{ + if(!active)return; + final long seqNo=sender.getCurrentSequenceNumber(); + if(seqNo<0)throw new IllegalStateException(); + while(!sender.isSentOut(seqNo)){ + Thread.sleep(5); + } + if(seqNo>-1){ + //wait until data has been sent out and acknowledged + while(active && !sender.haveAcknowledgementFor(seqNo)){ + sender.waitForAck(seqNo); + } + } + //TODO need to check if we can pause the sender... + //sender.pause(); + } + + //writes and wait for ack + protected void doWriteBlocking(byte[]data)throws IOException, InterruptedException{ + doWrite(data); + flush(); + } + + /** + * close the connection + * @throws IOException + */ + public void close()throws IOException{ + if(inputStream!=null)inputStream.close(); + if(outputStream!=null)outputStream.close(); + active=false; + close=true; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/83/d01fa7f1d6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/83/d01fa7f1d6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..1d41446 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/83/d01fa7f1d6ac001716b9ca6d5abb90bc @@ -0,0 +1,253 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + System.out.println("sendBlocking start"); + client.sendBlocking(data); + r=data.length; + sumLen+=r; + System.out.println("sendBlocking end"); + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取有数据socket + * 并且移除其它无用socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + index=i; + i=-1;//重新遍历 + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +/** + * 清除所有socket + */ +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/83/e044245edbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/83/e044245edbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..9f48531 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/83/e044245edbac001716b9ca6d5abb90bc @@ -0,0 +1,368 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;isessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&stopped) + { + //已经正常关闭 + } + else + { + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + } + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/84/7015bce5f7ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/84/7015bce5f7ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..25b7e89 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/84/7015bce5f7ab001710ff8a7c6bda0fb8 @@ -0,0 +1,87 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取有数据socket + * 并且移除其它socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + index=i; + i=-1;//重新遍历 + + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +/** + * 清除所有socket + */ +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/84/80036963c9ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/84/80036963c9ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..557fe8d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/84/80036963c9ac001716b9ca6d5abb90bc @@ -0,0 +1,605 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ControlPacket; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.packets.Shutdown; +import udt.packets.ControlPacket.ControlPacketType; +import udt.receiver.AckHistoryEntry; +import udt.receiver.AckHistoryWindow; +import udt.receiver.PacketHistoryWindow; +import udt.receiver.PacketPairWindow; +import udt.receiver.ReceiverLossList; +import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + +/** + * receiver part of a UDT entity + * @see UDTSender + */ +public class UDTReceiver { + + private static final Logger logger=Logger.getLogger(UDTReceiver.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //record seqNo of detected lostdata and latest feedback time + private final ReceiverLossList receiverLossList; + + //record each sent ACK and the sent time + private final AckHistoryWindow ackHistoryWindow; + + //Packet history window that stores the time interval between the current and the last seq. + private final PacketHistoryWindow packetHistoryWindow; + + //for storing the arrival time of the last received data packet + private volatile long lastDataPacketArrivalTime=0; + + //largest received data packet sequence number(LRSN) + private volatile long largestReceivedSeqNumber=0; + + //ACK event related + + //last Ack number + private long lastAckNumber=0; + + //largest Ack number ever acknowledged by ACK2 + private volatile long largestAcknowledgedAckNumber=-1; + + //EXP event related + + //a variable to record number of continuous EXP time-out events + private volatile long expCount=0; + + /*records the time interval between each probing pair + compute the median packet pair interval of the last + 16 packet pair intervals (PI) and the estimate link capacity.(packet/s)*/ + private final PacketPairWindow packetPairWindow; + + //estimated link capacity + long estimateLinkCapacity; + // the packet arrival rate + long packetArrivalSpeed; + + //round trip time, calculated from ACK/ACK2 pairs + long roundTripTime=0; + //round trip time variance + long roundTripTimeVar=roundTripTime/2; + + //to check the ACK, NAK, or EXP timer + private long nextACK; + //microseconds to next ACK event + private long ackTimerInterval=Util.getSYNTime(); + + private long nextNAK; + //microseconds to next NAK event + private long nakTimerInterval=Util.getSYNTime(); + + private long nextEXP; + //microseconds to next EXP event + private long expTimerInterval=100*Util.getSYNTime(); + + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + + //buffer size for storing data + private final long bufferSize; + + //stores received packets to be sent + private final BlockingQueuehandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + logger.info("haveNewData:失败"); + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + logger.info("largestReceivedSeqNumber:"+largestReceivedSeqNumber); + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + logger.info("sendNAK List:"+sequenceNumbers.size()); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/84/a05eab38e6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/84/a05eab38e6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..70064a3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/84/a05eab38e6ac001716b9ca6d5abb90bc @@ -0,0 +1,248 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + /** + * 接收数据写入文件 + */ + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + //空文件不会有数据 + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + break; + } + else + { + recData(); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/85/209583282cac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/85/209583282cac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..406472e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/85/209583282cac001710ff8a7c6bda0fb8 @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int sumNum=0; +private volatile int sumLen=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} + +/** + * 整理数据 + * @return + */ +private boolean check() +{ + if(sumNum>=buffer.length) + { + //检查成功 + if(sumLen==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i=buffer.length) + { + //检查成功 + if(sumLen==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/85/80f057855ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/85/80f057855ca800171a8482560d609ceb new file mode 100644 index 0000000..e266d43 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/85/80f057855ca800171a8482560d609ceb @@ -0,0 +1,227 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/85/90ae4b9621ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/85/90ae4b9621ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c92649a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/85/90ae4b9621ac001710ff8a7c6bda0fb8 @@ -0,0 +1,287 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + + +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/85/a0816d39a0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/85/a0816d39a0ad0017181ed9113883eda9 new file mode 100644 index 0000000..79a64ce --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/85/a0816d39a0ad0017181ed9113883eda9 @@ -0,0 +1,52 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.StringReader; + +import javax.swing.text.Document; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.xml.sax.InputSource; + +/** + * @author jinyu + * + */ +public class ReadXml { +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder=factory.newDocumentBuilder(); + Document doc = (Document) builder.parse(is); +} +public String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/85/c09cd59465a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/85/c09cd59465a800171a8482560d609ceb new file mode 100644 index 0000000..c24f75a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/85/c09cd59465a800171a8482560d609ceb @@ -0,0 +1,24 @@ +/** + * + */ +package judp; + +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/85/f09ac541b3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/85/f09ac541b3ad0017181ed9113883eda9 new file mode 100644 index 0000000..b283fb5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/85/f09ac541b3ad0017181ed9113883eda9 @@ -0,0 +1,504 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/86/4061804bb5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/86/4061804bb5ad0017181ed9113883eda9 new file mode 100644 index 0000000..3c4ed9c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/86/4061804bb5ad0017181ed9113883eda9 @@ -0,0 +1,522 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s0) + { + if(lastAckSequenceNumber/10000!=ackNumber/10000) + { + //修正 + //ackNumber 特别大,则会全部删除,特别小,一个都不会删除 + if(lastAckSequenceNumberthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + } + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/86/901545d3ceac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/86/901545d3ceac001716b9ca6d5abb90bc new file mode 100644 index 0000000..8d6a9c8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/86/901545d3ceac001716b9ca6d5abb90bc @@ -0,0 +1,216 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/86/b0f69645e1ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/86/b0f69645e1ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..ab51e34 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/86/b0f69645e1ac001716b9ca6d5abb90bc @@ -0,0 +1,187 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-lastTime)/1000); + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/87/905c92e81bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/87/905c92e81bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..b0190e5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/87/905c92e81bac001710ff8a7c6bda0fb8 @@ -0,0 +1,23 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] data; +public long id; +public void addData(byte[]data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int index=buf.getInt(); + int dataLen=buf.getInt(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/87/b04abcedceac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/87/b04abcedceac001716b9ca6d5abb90bc new file mode 100644 index 0000000..1a9a1c7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/87/b04abcedceac001716b9ca6d5abb90bc @@ -0,0 +1,221 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 + return false; + } + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/87/d06fb23ef8ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/87/d06fb23ef8ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c922679 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/87/d06fb23ef8ab001710ff8a7c6bda0fb8 @@ -0,0 +1,131 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +//private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + //移除已经检查成功的socket + for(int i=0;i> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + + + } + private void startThread() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + WeakReference objsocket=queue.take(); + if(objsocket.get()!=null) + { + judpSocket socket=objsocket.get(); + if(socket.getCloseState()) + { + socket.close(); + } + } + + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/88/300f6db6a1ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/88/300f6db6a1ad0017181ed9113883eda9 new file mode 100644 index 0000000..5bbf486 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/88/300f6db6a1ad0017181ed9113883eda9 @@ -0,0 +1,51 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + String path = TestSendFiles.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + ReadXml rd=new ReadXml(); + String xml= rd.readXml("config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + SendFiles send=new SendFiles(config[0], Integer.valueOf(config[1])); + FilesWatch watch=new FilesWatch(); + String dir=config[2]; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/88/40c685021dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/88/40c685021dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f9764fc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/88/40c685021dac001710ff8a7c6bda0fb8 @@ -0,0 +1,49 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer; +public long id; +private volatile int num=0; +private volatile int sum=0; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + + } + } +} +public boolean addData(byte[]data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + int index=buf.getInt(); + dataLen=buf.getInt(); + byte[] tmp=new byte[buf.limit()-buf.position()]; + buf.get(tmp); + buffer[index]=tmp; + num++; + sum+=tmp.length; +} + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/88/a03701d4e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/88/a03701d4e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..3f7dd9d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/88/a03701d4e4ac001716b9ca6d5abb90bc @@ -0,0 +1,235 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + ss.close(); + break; + } + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/88/c0bd27e169a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/88/c0bd27e169a800171a8482560d609ceb new file mode 100644 index 0000000..d730a23 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/88/c0bd27e169a800171a8482560d609ceb @@ -0,0 +1,109 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/88/f0cdb76ee4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/88/f0cdb76ee4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..a7f8c93 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/88/f0cdb76ee4ac001716b9ca6d5abb90bc @@ -0,0 +1,220 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + private String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private long sumBytes=0; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/89/10b16869e0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/89/10b16869e0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..fd0c49b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/89/10b16869e0ac001716b9ca6d5abb90bc @@ -0,0 +1,149 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + + } + long end=System.currentTimeMillis(); + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/89/20a9116191ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/89/20a9116191ad0017181ed9113883eda9 new file mode 100644 index 0000000..478d04b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/89/20a9116191ad0017181ed9113883eda9 @@ -0,0 +1,503 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 + + lastAckSequenceNumber=ackNumber; + } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/89/60482f9831ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/89/60482f9831ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..5e16be5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/89/60482f9831ac001710ff8a7c6bda0fb8 @@ -0,0 +1,337 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/timespan/1000; + sumBytes=0;//已经计算 + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8b/2028bc9e03ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/2028bc9e03ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f5ef8ed --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/2028bc9e03ac001710ff8a7c6bda0fb8 @@ -0,0 +1,77 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference objsocket=queue.take(); + if(objsocket.get()!=null) + { + judpSocket socket=objsocket.get(); + if(socket.getCloseState()) + { + + socket.close(); + } + } + + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8b/f049864a2dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/f049864a2dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..edbe122 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/f049864a2dac001710ff8a7c6bda0fb8 @@ -0,0 +1,100 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ +UDTSocket socket=SocketControls.getInstance().getSocket(); +judpSocket jsocket=new judpSocket(socket); +//judpSocket jsocket= sessionHandoff.take(); +return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8c/706d27faa0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/8c/706d27faa0ad0017181ed9113883eda9 new file mode 100644 index 0000000..04bf814 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8c/706d27faa0ad0017181ed9113883eda9 @@ -0,0 +1,50 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + ReadXml rd=new ReadXml(); + String xml= rd.readXml("config.xml"); + String[] config=null; + if(xml!=null) + { + + } + SendFiles send=new SendFiles("192.168.30.128", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8d/402cdc156aa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/8d/402cdc156aa800171a8482560d609ceb new file mode 100644 index 0000000..94865bd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8d/402cdc156aa800171a8482560d609ceb @@ -0,0 +1,113 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8d/e0ba0b7bd4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/8d/e0ba0b7bd4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..7963bec --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8d/e0ba0b7bd4ac001716b9ca6d5abb90bc @@ -0,0 +1,254 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8e/4072bac31bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/8e/4072bac31bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..573e0a2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8e/4072bac31bac001710ff8a7c6bda0fb8 @@ -0,0 +1,26 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public static void addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(); + hash.put(id, struct); + } + struct.a +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8e/40caa7ab5ba800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/8e/40caa7ab5ba800171a8482560d609ceb new file mode 100644 index 0000000..ac9ea61 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8e/40caa7ab5ba800171a8482560d609ceb @@ -0,0 +1,196 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }) + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8e/603dcdc705ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/8e/603dcdc705ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ff8d242 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8e/603dcdc705ac001710ff8a7c6bda0fb8 @@ -0,0 +1,92 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + private long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8e/c06f82a71aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/8e/c06f82a71aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..cbf2344 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8e/c06f82a71aac001710ff8a7c6bda0fb8 @@ -0,0 +1,13 @@ +/** + * + */ +package judp; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[] data; +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8f/70ff0f2bf7ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/8f/70ff0f2bf7ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..47fb712 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8f/70ff0f2bf7ab001710ff8a7c6bda0fb8 @@ -0,0 +1,125 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + for(int i=0;i=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 + if(highestReadSequenceNumber+1 hash=new ConcurrentHashMap(); +private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + //移除已经检查成功的socket + for(int i=0;i0){ + int len=Math.min(bb.remaining(),chunksize); + byte[]chunk=new byte[len]; + bb.get(chunk); + DataPacket packet=new DataPacket(); + seqNo=sender.getNextSequenceNumber(); + packet.setPacketSequenceNumber(seqNo); + packet.setSession(session); + packet.setDestinationID(session.getDestination().getSocketID()); + packet.setData(chunk); + //put the packet into the send queue + if(!sender.sendUdtPacket(packet, timeout, units)){ + throw new IOException("Queue full"); + } + } + if(length>0)active=true; + } + /** + * will block until the outstanding packets have really been sent out + * and acknowledged + */ + protected void flush() throws InterruptedException{ + if(!active)return; + final long seqNo=sender.getCurrentSequenceNumber(); + if(seqNo<0)throw new IllegalStateException(); + while(!sender.isSentOut(seqNo)){ + Thread.sleep(5); + } + if(seqNo>-1){ + //wait until data has been sent out and acknowledged + while(active && !sender.haveAcknowledgementFor(seqNo)){ + sender.waitForAck(seqNo); + } + } + //TODO need to check if we can pause the sender... + //sender.pause(); + } + + //writes and wait for ack + protected void doWriteBlocking(byte[]data)throws IOException, InterruptedException{ + doWrite(data); + flush(); + } + + /** + * close the connection + * @throws IOException + */ + public void close()throws IOException{ + if(inputStream!=null)inputStream.close(); + if(outputStream!=null)outputStream.close(); + active=false; + close=true; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/93/2080768c98ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/93/2080768c98ad0017181ed9113883eda9 new file mode 100644 index 0000000..cb3a344 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/93/2080768c98ad0017181ed9113883eda9 @@ -0,0 +1,36 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //192.168.30.128 + RecviceFiles rec=new RecviceFiles(); + String dir="/home/jinyu/recFiles"; + rec.setDir(dir); + rec.start("192.168.30.128", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/93/b0b2529ed9ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/93/b0b2529ed9ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..3735d11 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/93/b0b2529ed9ac001716b9ca6d5abb90bc @@ -0,0 +1,154 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/93/e0abad5a03ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/93/e0abad5a03ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..6135c1a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/93/e0abad5a03ac001710ff8a7c6bda0fb8 @@ -0,0 +1,21 @@ +/** + * + */ +package judp; + + +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + private final long id=-1; + public SocketReference(T referent) { + super(referent); + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/93/f0f80f7ad8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/93/f0f80f7ad8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..855d7e3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/93/f0f80f7ad8ac001716b9ca6d5abb90bc @@ -0,0 +1,363 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + public SocketReference(T referent, long id, ReferenceQueue q) { + super(referent,q); + this.socketid=id; + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/94/80509c7cd5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/94/80509c7cd5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..76c9a58 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/94/80509c7cd5ac001716b9ca6d5abb90bc @@ -0,0 +1,254 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/94/c0c4843f89ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/94/c0c4843f89ad0017181ed9113883eda9 new file mode 100644 index 0000000..848dcde --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/94/c0c4843f89ad0017181ed9113883eda9 @@ -0,0 +1,190 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.SocketException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.SequenceNumber; + +/** + * Client side of a client-server UDT connection. + * Once established, the session provides a valid {@link UDTSocket}. + */ +public class ClientSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private UDPEndPoint endPoint; + + public ClientSession(UDPEndPoint endPoint, Destination dest)throws SocketException{ + super("ClientSession localPort="+endPoint.getLocalPort(),dest); + this.endPoint=endPoint; + logger.info("Created "+toString()); + } + + /** + * send connection handshake until a reply from server is received + * TODO check for timeout + * @throws InterruptedException + * @throws IOException + */ + + public void connect() throws InterruptedException,IOException{ + int n=0; + + while(getState()!=ready){ + + sendHandShake(); + if(getState()==invalid)throw new IOException("Can't connect!"); + n++; + if(getState()!=ready)Thread.sleep(500); + } + + cc.init(); + logger.info("Connected, "+n+" handshake packets sent"); + } + + @Override + public void received(UDTPacket packet, Destination peer) { + + lastPacket=packet; + + if (packet instanceof ConnectionHandshake) { + ConnectionHandshake hs=(ConnectionHandshake)packet; + + logger.info("Received connection handshake from "+peer+"\n"+hs); + + if (getState()!=ready) { + if(hs.getConnectionType()==1){ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + sendConfirmation(hs); + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + else{ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + setState(ready); + Thread.sleep(50); + logger.info("初始序列置回:"+hs.getInitialSeqNo()); + System.out.println("初始序列置回1:"+hs.getInitialSeqNo()); + this.setInitialSequenceNumber(hs.getInitialSeqNo());//cd 必须重置 + System.out.println("初始序列置回2:"+this.getInitialSequenceNumber()); + socket=new UDTSocket(endPoint,this); + + + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + } + } + + if(getState() == ready) { + + if(packet instanceof Shutdown){ + setState(shutdown); + active=false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + active = true; + try{ + if(packet.forSender()){ + socket.getSender().receive(lastPacket); + }else{ + socket.getReceiver().receive(lastPacket); + } + }catch(Exception ex){ + //session is invalid + logger.log(Level.SEVERE,"Error in "+toString(),ex); + setState(invalid); + } + return; + } + } + + + //handshake for connect + protected void sendHandShake()throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(ConnectionHandshake.CONNECTION_TYPE_REGULAR); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + long initialSequenceNo=SequenceNumber.random(); + setInitialSequenceNumber(initialSequenceNo); + handshake.setInitialSeqNo(initialSequenceNo); + handshake.setPacketSize(getDatagramSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending "+handshake); + endPoint.doSend(handshake); + } + + //2nd handshake for connect + protected void sendConfirmation(ConnectionHandshake hs)throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(-1); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + handshake.setInitialSeqNo(hs.getInitialSeqNo()); + handshake.setPacketSize(hs.getPacketSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending confirmation "+handshake); + endPoint.doSend(handshake); + } + + + public UDTPacket getLastPkt(){ + return lastPacket; + } + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/94/c0e9a906f7ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/94/c0e9a906f7ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..8e5e548 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/94/c0e9a906f7ab001710ff8a7c6bda0fb8 @@ -0,0 +1,115 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private long sumBytes=0; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/94/c0f5f1f904ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/94/c0f5f1f904ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..1865828 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/94/c0f5f1f904ac001710ff8a7c6bda0fb8 @@ -0,0 +1,33 @@ +/** + * + */ +package judp; + + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + public SocketReference(T referent, long socketID, ReferenceQueue q) { + super(referent,q); + this.socketid=id; + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/95/106ce8205ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/95/106ce8205ca800171a8482560d609ceb new file mode 100644 index 0000000..5a0a8c9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/95/106ce8205ca800171a8482560d609ceb @@ -0,0 +1,199 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + clientSession. + } + + } + + }); + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/95/80feebb422ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/95/80feebb422ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..38700f4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/95/80feebb422ac001710ff8a7c6bda0fb8 @@ -0,0 +1,217 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * 读取数据 + * @return + */ + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(client.isClose()) + { + return null; + } + r=client.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; + } + public int read(byte[]data) + { + try { + return client.read(data); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return -1; + } + + /** + * 关闭 + */ + public void close() + { + if(client!=null) + { + if(sumLen==0) + { + //没有发送数据 + //立即关闭 + try { + if(!client.isClose()) + client.shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + //开始缓存 + //SocketManager.getInstance().add(client); + if(!client.isClose()) + client.close(); + } + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/95/d0b13b4665a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/95/d0b13b4665a800171a8482560d609ceb new file mode 100644 index 0000000..f1d0563 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/95/d0b13b4665a800171a8482560d609ceb @@ -0,0 +1,67 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + + for(Entry entry:hash.entrySet()) + { + + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/96/50660e361aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/96/50660e361aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..589d1a5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/96/50660e361aac001710ff8a7c6bda0fb8 @@ -0,0 +1,74 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + byte[][] result=new byte[num][]; + for(int i=0;i=buffer.length) + { + //检查成功 + + } +} +public boolean addData(byte[]data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + int index=buf.getInt(); + dataLen=buf.getInt(); + byte[] tmp=new byte[buf.limit()-buf.position()]; + buf.get(tmp); + buffer[index]=tmp; + num++; + sum+=tmp.length; +} + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/98/40b88e4fdeac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/98/40b88e4fdeac001716b9ca6d5abb90bc new file mode 100644 index 0000000..73c5430 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/98/40b88e4fdeac001716b9ca6d5abb90bc @@ -0,0 +1,183 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long startTime=System.currentTimeMillis(); + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + long speed=sumBytes/((System.currentTimeMillis()-startTime)/1000); + } + + log.info("文件接收速度:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/98/806ec5ec63a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/98/806ec5ec63a800171a8482560d609ceb new file mode 100644 index 0000000..3b94973 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/98/806ec5ec63a800171a8482560d609ceb @@ -0,0 +1,21 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private ConcurrentHashMap hash=new ConcurrentHashMap(); +public void addSocket(UDTSocket socket) +{ + hash.get(socket.getSession().getDestination().getSocketID()); + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/98/905f0aa3a3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/98/905f0aa3a3ad0017181ed9113883eda9 new file mode 100644 index 0000000..37a1e18 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/98/905f0aa3a3ad0017181ed9113883eda9 @@ -0,0 +1,369 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +//private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + break; + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + //readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + // readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/98/e0ddaa03e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/98/e0ddaa03e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..4d70528 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/98/e0ddaa03e4ac001716b9ca6d5abb90bc @@ -0,0 +1,209 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + ConcurrentLinkedQueue recData=new ConcurrentLinkedQueue(); + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/99/0038300d04ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/99/0038300d04ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..71a5f57 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/99/0038300d04ac001710ff8a7c6bda0fb8 @@ -0,0 +1,70 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (SocketReference) q.remove()) != null) { + + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/99/108ba746dbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/99/108ba746dbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..6275295 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/99/108ba746dbac001716b9ca6d5abb90bc @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int sumNum=0; +private volatile int sumLen=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} + +/** + * 整理数据 + * @return + */ +private boolean check() +{ + if(sumNum>=buffer.length) + { + //检查成功 + if(sumLen==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;ihandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + logger.info("sendNAK:"+currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + logger.info("largestReceivedSeqNumber:"+largestReceivedSeqNumber); + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + logger.info("sendNAK List:"+sequenceNumbers.size()); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9a/5047c66c59ac00171c63d91e40f02a62 b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/5047c66c59ac00171c63d91e40f02a62 new file mode 100644 index 0000000..66b8f57 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/5047c66c59ac00171c63d91e40f02a62 @@ -0,0 +1,153 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9a/9020bf8105ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/9020bf8105ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..82c88da --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/9020bf8105ac001710ff8a7c6bda0fb8 @@ -0,0 +1,92 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9a/90e58c27dbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/90e58c27dbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..b759723 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/90e58c27dbac001716b9ca6d5abb90bc @@ -0,0 +1,291 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import udt.util.ReceiveBuffer; + +/** + * The UDTInputStream receives data blocks from the {@link UDTSocket} + * as they become available, and places them into an ordered, + * bounded queue (the flow window) for reading by the application + * + * + */ +public class UDTInputStream extends InputStream { + + //the socket owning this inputstream + private final UDTSocket socket; + + private final ReceiveBuffer receiveBuffer; + + //set to 'false' by the receiver when it gets a shutdown signal from the peer + //see the noMoreData() method + private final AtomicBoolean expectMoreData=new AtomicBoolean(true); + + private volatile boolean closed=false; + + private volatile boolean blocking=true; + + private volatile boolean hasData=false;//cd + + + + /** + * create a new {@link UDTInputStream} connected to the given socket + * @param socket - the {@link UDTSocket} + * @throws IOException + */ + public UDTInputStream(UDTSocket socket)throws IOException{ + this.socket=socket; + int capacity=socket!=null? 2 * socket.getSession().getFlowWindowSize() : 128 ; + long initialSequenceNum=socket!=null?socket.getSession().getInitialSequenceNumber():1; + receiveBuffer=new ReceiveBuffer(capacity,initialSequenceNum); + } + + private final byte[]single=new byte[1]; + + @Override + public int read()throws IOException{ + int b=0; + while(b==0) + b=read(single); + + if(b>0){ + return single[0]; + } + else { + return b; + } + } + + private AppData currentChunk=null; + //offset into currentChunk + int offset=0; + long id=-1; + @Override + public int read(byte[]target)throws IOException{ + try{ + int read=0; + updateCurrentChunk(false); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(blocking && read==0); + } + + if(read>0)return read; + if(closed)return -1; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; + //no more data + return -1; + + }catch(Exception ex){ + IOException e= new IOException(); + e.initCause(ex); + throw e; + } + } + + /** + * Reads the next valid chunk of application data from the queue
+ * + * In blocking mode,this method will block until data is available or the socket is closed, + * otherwise it will wait for at most 10 milliseconds. + * + * @throws InterruptedException + */ + private void updateCurrentChunk(boolean block)throws IOException{ + if(currentChunk!=null)return; + + while(true){ + try{ + if(block){ + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); + while (!closed && currentChunk==null){ + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); + } + } + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); + + }catch(InterruptedException ie){ + IOException ex=new IOException(); + ex.initCause(ie); + throw ex; + } + return; + } + } + + /** + * new application data + * @param data + * + */ + protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + hasData=true; + return receiveBuffer.offer(new AppData(sequenceNumber,data)); + } + + @Override + public void close()throws IOException{ + if(closed)return; + closed=true; + noMoreData(); + } + + public UDTSocket getSocket(){ + return socket; + } + + /** + * sets the blocking mode + * @param block + */ + public void setBlocking(boolean block){ + this.blocking=block; + } + + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + + /** + * notify the input stream that there is no more data + * @throws IOException + */ + protected void noMoreData()throws IOException{ + expectMoreData.set(false); + } + + /** + * 判断有没有数据进来 + * cd + * @return + */ + public boolean isHasData() + { + return hasData; + } + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + receiveBuffer.resetBufMaster(isRead); + + } + + /** + * 设置大数据读取 + * 默认 false + * @param islarge + */ + public void setLargeRead(boolean islarge) + { + receiveBuffer.setLargeRead(islarge); + } + /** + * used for storing application data and the associated + * sequence number in the queue in ascending order + */ + public static class AppData implements Comparable{ + final long sequenceNumber; + final byte[] data; + public AppData(long sequenceNumber, byte[]data){ + this.sequenceNumber=sequenceNumber; + this.data=data; + } + + @Override + public int compareTo(AppData o) { + return (int)(sequenceNumber-o.sequenceNumber); + } + + @Override + public String toString(){ + return sequenceNumber+"["+data.length+"]"; + } + + public long getSequenceNumber(){ + return sequenceNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9a/a0ca38a134ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/a0ca38a134ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..a92c305 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/a0ca38a134ac001710ff8a7c6bda0fb8 @@ -0,0 +1,338 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(getCloseState()) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + /** + * 接收数据写入文件 + */ + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + // + recQueue.clear(); + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + //空文件不会有数据 + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + break; + } + else + { + recData(); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9b/a0c5a62123ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/9b/a0c5a62123ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..9296ded --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9b/a0c5a62123ac001710ff8a7c6bda0fb8 @@ -0,0 +1,240 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * 读取数据 + * 只和split发送对应 + * @return + */ + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(client.isClose()) + { + return null; + } + r=client.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; + } + public int read(byte[]data) + { + try { + return client.read(data); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return -1; + } + + /** + * 关闭 + */ + public void close() + { + if(client!=null) + { + if(sumLen==0) + { + //没有发送数据 + //立即关闭 + try { + if(!client.isClose()) + client.shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + //开始缓存 + //SocketManager.getInstance().add(client); + if(!client.isClose()) + client.close(); + } + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9c/2087ada01fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/9c/2087ada01fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..6155966 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9c/2087ada01fac001710ff8a7c6bda0fb8 @@ -0,0 +1,35 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); + private ConcurrentLinkedQueue queue=new ConcurrentLinkedQueue(); +public boolean addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + boolean r= struct.addData(data); + if(r) + { + queue.offer(struct.getData()); + } + return r; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9c/701d65425ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/9c/701d65425ca800171a8482560d609ceb new file mode 100644 index 0000000..5bb506b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9c/701d65425ca800171a8482560d609ceb @@ -0,0 +1,216 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + } + + }); + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9c/d0238e50c3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/9c/d0238e50c3ad0017181ed9113883eda9 new file mode 100644 index 0000000..fd0de3f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9c/d0238e50c3ad0017181ed9113883eda9 @@ -0,0 +1,494 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9c/d051dafe19ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/9c/d051dafe19ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..892959d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9c/d051dafe19ac001710ff8a7c6bda0fb8 @@ -0,0 +1,74 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + byte[][] result=new byte[num][]; + for(int i=0;i hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + entry.getValue().getSocket(); + } + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9d/5049179dd5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/9d/5049179dd5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..eccfe90 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9d/5049179dd5ac001716b9ca6d5abb90bc @@ -0,0 +1,259 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9d/a0bc950e1eac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/9d/a0bc950e1eac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..4958bf3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9d/a0bc950e1eac001710ff8a7c6bda0fb8 @@ -0,0 +1,27 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public static void addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(); + hash.put(id, struct); + } + struct.addData(data); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9e/e01bd697e1ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/9e/e01bd697e1ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..9c4eb48 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9e/e01bd697e1ac001716b9ca6d5abb90bc @@ -0,0 +1,198 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/timespan/1000; + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9f/00cb17ba1dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/9f/00cb17ba1dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c3490cd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9f/00cb17ba1dac001710ff8a7c6bda0fb8 @@ -0,0 +1,65 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + int index=0; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9f/d08d5d2106ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/9f/d08d5d2106ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..783f49c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9f/d08d5d2106ac001710ff8a7c6bda0fb8 @@ -0,0 +1,71 @@ +/** + * + */ +package Test; + +import java.util.concurrent.TimeUnit; + +import judp.judpServer; +import judp.judpSocket; + +/** + * @author jinyu + * + */ +public class TestServer { + public static void main(String[] args) { + + judpServer server=new judpServer("127.0.0.1",5555); + server.start(); + while(true) + { + judpSocket socket=server.accept(); + // + + Thread rec=new Thread(new Runnable() { + @Override + public void run() { + try + { + byte[] data=new byte[1024]; + int r=0; + while(r!=-1) + { + r=socket.readData(data); + if(r==0) + { + + try { + TimeUnit.MILLISECONDS.sleep(100); + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if(r==-1) + { + System.out.println("读取-1退出"); + break; + } + byte[]tmp=new byte[r]; + System.arraycopy(data, 0, tmp, 0, r); + System.out.println(new String(tmp)); + + } + //socket.close(); + } + catch(Exception ex) + { + ex.printStackTrace(); + } + }} + ); + rec.setDaemon(true); + rec.setName(String.valueOf(socket.socketID)); + rec.start(); + + } + + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a/30e9d046d4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/a/30e9d046d4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..b9d5031 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a/30e9d046d4ac001716b9ca6d5abb90bc @@ -0,0 +1,248 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a/50ae4bb952ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a/50ae4bb952ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..99a1b1e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a/50ae4bb952ac001710ff8a7c6bda0fb8 @@ -0,0 +1,150 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i20) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else + { + + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a/a081b90164a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/a/a081b90164a800171a8482560d609ceb new file mode 100644 index 0000000..ceb1ed1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a/a081b90164a800171a8482560d609ceb @@ -0,0 +1,25 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private ConcurrentHashMap hash=new ConcurrentHashMap(); +public void addSocket(UDTSocket socket) +{ + judpGroupSocket group=hash.get(socket.getSession().getDestination().getSocketID()); + if(group==null) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a/c0ee8e47e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/a/c0ee8e47e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..99c22aa --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a/c0ee8e47e4ac001716b9ca6d5abb90bc @@ -0,0 +1,211 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a/d022dccc6da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/a/d022dccc6da800171a8482560d609ceb new file mode 100644 index 0000000..a93cc94 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a/d022dccc6da800171a8482560d609ceb @@ -0,0 +1,35 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(Test.TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("127.0.0.1", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a/d05ac2d168a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/a/d05ac2d168a800171a8482560d609ceb new file mode 100644 index 0000000..5ae29cc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a/d05ac2d168a800171a8482560d609ceb @@ -0,0 +1,71 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + entry.getValue().getSocket(); + } + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a/d0c43373c3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/a/d0c43373c3ad0017181ed9113883eda9 new file mode 100644 index 0000000..9614ec0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a/d0c43373c3ad0017181ed9113883eda9 @@ -0,0 +1,492 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a0/308af7d8f8ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a0/308af7d8f8ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c4c0b93 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a0/308af7d8f8ab001710ff8a7c6bda0fb8 @@ -0,0 +1,351 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.PacketFactory; +import udt.util.UDTThreadFactory; + +/** + * the UDPEndpoint takes care of sending and receiving UDP network packets, + * dispatching them to the correct {@link UDTSession} + */ +public class UDPEndPoint { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private final int port; + + private final DatagramSocket dgSocket; + + //active sessions keyed by socket ID + private final Mapsessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&stopped) + { + //已经正常关闭 + } + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a0/60b6f0541dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a0/60b6f0541dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..41c29ef --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a0/60b6f0541dac001710ff8a7c6bda0fb8 @@ -0,0 +1,62 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + int index=0; + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a0/e0c0b8d904ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a0/e0c0b8d904ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..9c8fbec --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a0/e0c0b8d904ac001710ff8a7c6bda0fb8 @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID()); + queue.add(tmp); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a1/003e3e7b4fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a1/003e3e7b4fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..4a2ed8f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a1/003e3e7b4fac001710ff8a7c6bda0fb8 @@ -0,0 +1,243 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a1/a07bc2d560ac00171ca19969f19d2325 b/.metadata/.plugins/org.eclipse.core.resources/.history/a1/a07bc2d560ac00171ca19969f19d2325 new file mode 100644 index 0000000..1264aed --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a1/a07bc2d560ac00171ca19969f19d2325 @@ -0,0 +1,248 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + System.out.println("sendBlocking start"); + client.send(data); + r=data.length; + sumLen+=r; + System.out.println("sendBlocking end"); + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a1/d04b3b71a5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/a1/d04b3b71a5ad0017181ed9113883eda9 new file mode 100644 index 0000000..9842219 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a1/d04b3b71a5ad0017181ed9113883eda9 @@ -0,0 +1,56 @@ +/** + * 文件名:TestSendFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpSendFile; + +/** + * + * 项目名称:judp + * 类名称:TestSendFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:25 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:25 + * 修改备注: + * @version + * + */ +public class TestSendFile { + + /** + + * TODO(这里描述这个方法适用条件 – 可选) + + * @param name + + * @return + + * + + + */ + public static void main(String[] args) { + judpSendFile jsend=new judpSendFile("192.168.10.86",5555); + jsend.startSend(); + + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a2/20852d9403ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a2/20852d9403ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..9cbb6de --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a2/20852d9403ac001710ff8a7c6bda0fb8 @@ -0,0 +1,76 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + + + } + private void startThread() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference objsocket=queue.take(); + if(objsocket.get()!=null) + { + judpSocket socket=objsocket.get(); + if(socket.getCloseState()) + { + socket.close(); + } + } + + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a2/407e00c504ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a2/407e00c504ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..8e9a497 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a2/407e00c504ac001710ff8a7c6bda0fb8 @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID()); + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a2/5061348b26ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a2/5061348b26ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c1a18f2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a2/5061348b26ac001710ff8a7c6bda0fb8 @@ -0,0 +1,86 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i list=new ArrayList(); +public judpGroupSocket() +{ + +} +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} +public judpGroupSocket getSocket() +{ + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a3/401ed82266ac00171f75fe2361138dfd b/.metadata/.plugins/org.eclipse.core.resources/.history/a3/401ed82266ac00171f75fe2361138dfd new file mode 100644 index 0000000..d7a45f2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a3/401ed82266ac00171f75fe2361138dfd @@ -0,0 +1,236 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.net.DatagramPacket; +import java.util.Random; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.util.UDTStatistics; + +public abstract class UDTSession { + + private static final Logger logger=Logger.getLogger(UDTSession.class.getName()); + + protected int mode; + protected volatile boolean active; + private volatile int state=start; + protected volatile UDTPacket lastPacket; + + //state constants + public static final int start=0; + public static final int handshaking=1; + public static final int ready=2; + public static final int keepalive=3; + public static final int shutdown=4; + + public static final int invalid=99; + + protected volatile UDTSocket socket; + + protected final UDTStatistics statistics; + + protected int receiveBufferSize=64*32768; + + protected final CongestionControl cc; + + //cache dgPacket (peer stays the same always) + private DatagramPacket dgPacket; + + /** + * flow window size, i.e. how many data packets are + * in-flight at a single time + */ + protected int flowWindowSize=1024; + + /** + * remote UDT entity (address and socket ID) + */ + protected final Destination destination; + + /** + * local port + */ + protected int localPort; + + + public static final int DEFAULT_DATAGRAM_SIZE=UDPEndPoint.DATAGRAM_SIZE; + + /** + * key for a system property defining the CC class to be used + * @see CongestionControl + */ + public static final String CC_CLASS="udt.congestioncontrol.class"; + + /** + * Buffer size (i.e. datagram size) + * This is negotiated during connection setup + */ + protected int datagramSize=DEFAULT_DATAGRAM_SIZE; + + protected Long initialSequenceNumber=null; + + protected final long mySocketID; + + private final static AtomicLong nextSocketID=new AtomicLong(20+new Random().nextInt(5000)); + + + public UDTSession(String description, Destination destination){ + statistics=new UDTStatistics(description); + mySocketID=nextSocketID.incrementAndGet(); + this.destination=destination; + this.dgPacket=new DatagramPacket(new byte[0],0,destination.getAddress(),destination.getPort()); + String clazzP=System.getProperty(CC_CLASS,UDTCongestionControl.class.getName()); + Object ccObject=null; + try{ + Classclazz=Class.forName(clazzP); + ccObject=clazz.getDeclaredConstructor(UDTSession.class).newInstance(this); + }catch(Exception e){ + logger.log(Level.WARNING,"Can't setup congestion control class <"+clazzP+">, using default.",e); + ccObject=new UDTCongestionControl(this); + } + cc=(CongestionControl)ccObject; + logger.info("Using "+cc.getClass().getName()); + } + + + public abstract void received(UDTPacket packet, Destination peer); + + + public UDTSocket getSocket() { + return socket; + } + + public CongestionControl getCongestionControl() { + return cc; + } + + public int getState() { + return state; + } + + public void setMode(int mode) { + this.mode = mode; + } + + public void setSocket(UDTSocket socket) { + this.socket = socket; + } + + public void setState(int state) { + logger.info(toString()+" connection state CHANGED to <"+state+">"); + this.state = state; + } + + public boolean isReady(){ + return state==ready; + } + + public boolean isActive() { + return active == true; + } + + public void setActive(boolean active) { + this.active = active; + } + + public boolean isShutdown(){ + return state==shutdown || state==invalid; + } + + public Destination getDestination() { + return destination; + } + + public int getDatagramSize() { + return datagramSize; + } + + public void setDatagramSize(int datagramSize) { + this.datagramSize = datagramSize; + } + + public int getReceiveBufferSize() { + return receiveBufferSize; + } + + public void setReceiveBufferSize(int bufferSize) { + this.receiveBufferSize = bufferSize; + } + + public int getFlowWindowSize() { + return flowWindowSize; + } + + public void setFlowWindowSize(int flowWindowSize) { + this.flowWindowSize = flowWindowSize; + } + + public UDTStatistics getStatistics(){ + return statistics; + } + + public long getSocketID(){ + return mySocketID; + } + + + public synchronized long getInitialSequenceNumber(){ + if(initialSequenceNumber==null){ + initialSequenceNumber=1l; //TODO must be random? + } + return initialSequenceNumber; + } + + public synchronized void setInitialSequenceNumber(long initialSequenceNumber){ + this.initialSequenceNumber=initialSequenceNumber; + } + + public DatagramPacket getDatagram(){ + return dgPacket; + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append(super.toString()); + sb.append(" ["); + sb.append("socketID=").append(this.mySocketID); + sb.append(" ]"); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a3/a0965bb1e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/a3/a0965bb1e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..aad5ca7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a3/a0965bb1e4ac001716b9ca6d5abb90bc @@ -0,0 +1,223 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + if(writeFile(tmp)) + { + ss.close(); + break; + } + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a3/e0491a3469a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/a3/e0491a3469a800171a8482560d609ceb new file mode 100644 index 0000000..121c403 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a3/e0491a3469a800171a8482560d609ceb @@ -0,0 +1,91 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;i hash=new ConcurrentHashMap(); +//private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + //移除已经检查成功的socket + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a5/2062891a03ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a5/2062891a03ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..addcb39 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a5/2062891a03ac001710ff8a7c6bda0fb8 @@ -0,0 +1,22 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketQueue extends WeakReference { + public SocketQueue(T referent) { + super(referent); + + } + +private long id=-1; + public +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a6/9039b1d7dfac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/a6/9039b1d7dfac001716b9ca6d5abb90bc new file mode 100644 index 0000000..d7c1f11 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a6/9039b1d7dfac001716b9ca6d5abb90bc @@ -0,0 +1,187 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long startTime=System.currentTimeMillis(); + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + startTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-startTime)/1000); + } + catch(Exception ex) + { + + } + log.info("文件接收速度:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a7/00e268836da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/00e268836da800171a8482560d609ceb new file mode 100644 index 0000000..35194ca --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/00e268836da800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFile.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + SendFiles send=new SendFiles("127.0.0.1", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a7/30568a8fa0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/30568a8fa0ad0017181ed9113883eda9 new file mode 100644 index 0000000..a95a751 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/30568a8fa0ad0017181ed9113883eda9 @@ -0,0 +1,53 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; + +/** + * @author jinyu + * + */ +public class ReadXml { +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder=factory.newDocumentBuilder(); + Document doc = (Document) builder.parse(is); + doc.gete +} +public String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a7/70b19de71dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/70b19de71dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..121c7d0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/70b19de71dac001710ff8a7c6bda0fb8 @@ -0,0 +1,68 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a7/a0902db74fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/a0902db74fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..2331cbf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/a0902db74fac001710ff8a7c6bda0fb8 @@ -0,0 +1,139 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(this.islagerRead) + { + //cd + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a8/4095613d68a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/a8/4095613d68a800171a8482560d609ceb new file mode 100644 index 0000000..d5fc4e8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a8/4095613d68a800171a8482560d609ceb @@ -0,0 +1,79 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + i=-1;//重新遍历 + index=i; + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + //cd 添加 + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a8/803e3c42d7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/a8/803e3c42d7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..6318e80 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a8/803e3c42d7ac001716b9ca6d5abb90bc @@ -0,0 +1,279 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + System.out.println("sendBlocking start"); + client.sendBlocking(data); + r=data.length; + sumLen+=r; + System.out.println("sendBlocking end"); + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a8/c021eb1429ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/a8/c021eb1429ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..238736e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a8/c021eb1429ac001710ff8a7c6bda0fb8 @@ -0,0 +1,99 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a8/e00509dad7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/a8/e00509dad7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..9177c05 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a8/e00509dad7ac001716b9ca6d5abb90bc @@ -0,0 +1,143 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private boolean isRWMaster=true;//与默认值一致 +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + this.isRWMaster=isRead; + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.islagerRead=islarge; +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a9/20cde3669fad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/20cde3669fad0017181ed9113883eda9 new file mode 100644 index 0000000..8e092e4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/20cde3669fad0017181ed9113883eda9 @@ -0,0 +1,33 @@ +/** + * + */ +package net.File; + +import java.io.File; +import java.io.StringReader; + +import javax.swing.text.Document; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.xml.sax.InputSource; + +/** + * @author jinyu + * + */ +public class ReadXml { +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return null; + } + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder=factory.newDocumentBuilder(); + Document doc = (Document) builder.parse(is); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a9/40e9ecc6e6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/40e9ecc6e6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..6584270 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/40e9ecc6e6ac001716b9ca6d5abb90bc @@ -0,0 +1,249 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + /** + * 接收数据写入文件 + */ + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + //空文件不会有数据 + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + break; + } + else + { + recData(); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + recQueue.clear(); + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a9/500e93c5d5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/500e93c5d5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..a3a9de9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/500e93c5d5ac001716b9ca6d5abb90bc @@ -0,0 +1,265 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a9/50f9bfc666a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/50f9bfc666a800171a8482560d609ceb new file mode 100644 index 0000000..938c3ee --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/50f9bfc666a800171a8482560d609ceb @@ -0,0 +1,54 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + for( int i = 0 ; i < list.size() ; i++) { + try { + if(list.get(i).getInputStream().isHasData()) + { + return list.get(i); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a9/8036f5d929ad001713e0de43c08806fd b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/8036f5d929ad001713e0de43c08806fd new file mode 100644 index 0000000..56330c7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/8036f5d929ad001713e0de43c08806fd @@ -0,0 +1,188 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.SocketException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.SequenceNumber; + +/** + * Client side of a client-server UDT connection. + * Once established, the session provides a valid {@link UDTSocket}. + */ +public class ClientSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private UDPEndPoint endPoint; + + public ClientSession(UDPEndPoint endPoint, Destination dest)throws SocketException{ + super("ClientSession localPort="+endPoint.getLocalPort(),dest); + this.endPoint=endPoint; + logger.info("Created "+toString()); + } + + /** + * send connection handshake until a reply from server is received + * TODO check for timeout + * @throws InterruptedException + * @throws IOException + */ + + public void connect() throws InterruptedException,IOException{ + int n=0; + + while(getState()!=ready){ + + sendHandShake(); + if(getState()==invalid)throw new IOException("Can't connect!"); + n++; + if(getState()!=ready)Thread.sleep(500); + } + + cc.init(); + logger.info("Connected, "+n+" handshake packets sent"); + } + + @Override + public void received(UDTPacket packet, Destination peer) { + + lastPacket=packet; + + if (packet instanceof ConnectionHandshake) { + ConnectionHandshake hs=(ConnectionHandshake)packet; + + logger.info("Received connection handshake from "+peer+"\n"+hs); + + if (getState()!=ready) { + if(hs.getConnectionType()==1){ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + sendConfirmation(hs); + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + else{ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + setState(ready); + TimeUnit.MILLISECONDS.sleep(50); + this.setInitialSequenceNumber(hs.getInitialSeqNo());//cd 必须重置 + socket=new UDTSocket(endPoint,this); + + + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + } + } + + if(getState() == ready) { + + if(packet instanceof Shutdown){ + setState(shutdown); + active=false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + active = true; + try{ + if(packet.forSender()){ + socket.getSender().receive(lastPacket); + }else{ + socket.getReceiver().receive(lastPacket); + } + }catch(Exception ex){ + //session is invalid + logger.log(Level.SEVERE,"Error in "+toString(),ex); + setState(invalid); + } + return; + } + } + + + //handshake for connect + protected void sendHandShake()throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(ConnectionHandshake.CONNECTION_TYPE_REGULAR); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + long initialSequenceNo=SequenceNumber.random(); + setInitialSequenceNumber(initialSequenceNo); + handshake.setInitialSeqNo(initialSequenceNo); + handshake.setPacketSize(getDatagramSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending "+handshake); + endPoint.doSend(handshake); + } + + //2nd handshake for connect + protected void sendConfirmation(ConnectionHandshake hs)throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(-1); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + handshake.setInitialSeqNo(hs.getInitialSeqNo()); + handshake.setPacketSize(hs.getPacketSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending confirmation "+handshake); + endPoint.doSend(handshake); + } + + + public UDTPacket getLastPkt(){ + return lastPacket; + } + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a9/b04660ada0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/b04660ada0ad0017181ed9113883eda9 new file mode 100644 index 0000000..12007a3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/b04660ada0ad0017181ed9113883eda9 @@ -0,0 +1,61 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/** + * @author jinyu + * + */ +public class ReadXml { +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder=factory.newDocumentBuilder(); + Document doc = (Document) builder.parse(is); + NodeList list=doc.getElementsByTagName("IP"); + String ip= list.item(0).getTextContent(); + list=doc.getElementsByTagName("Port"); + String port=list.item(0).getTextContent(); + list=doc.getElementsByTagName("Dir"); + String dir=list.item(0).getTextContent(); + String strxml=ip+","+port+","+dir; + return strxml + } +public String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a9/c081497ec9ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/c081497ec9ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..1adc8b6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/c081497ec9ac001716b9ca6d5abb90bc @@ -0,0 +1,355 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.PacketFactory; +import udt.util.UDTThreadFactory; + +/** + * the UDPEndpoint takes care of sending and receiving UDP network packets, + * dispatching them to the correct {@link UDTSession} + */ +public class UDPEndPoint { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private final int port; + + private final DatagramSocket dgSocket; + + //active sessions keyed by socket ID + private final Mapsessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + //logger.log(Level.INFO, "接受数据: "+packet.getPacketSequenceNumber()); + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&stopped) + { + //已经正常关闭 + } + else + { + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + } + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a9/c0ecdbb15ba800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/c0ecdbb15ba800171a8482560d609ceb new file mode 100644 index 0000000..f4ef351 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a9/c0ecdbb15ba800171a8482560d609ceb @@ -0,0 +1,196 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }); + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/aa/403bb575e1ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/aa/403bb575e1ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..e150146 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/aa/403bb575e1ac001716b9ca6d5abb90bc @@ -0,0 +1,187 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-lastTime)/1000); + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/aa/4083116e1dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/aa/4083116e1dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..0df0b5f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/aa/4083116e1dac001710ff8a7c6bda0fb8 @@ -0,0 +1,63 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + int index=0; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i"); + FileOutputStream fos=null; + try{ + fos=new FileOutputStream(file); + + System.out.println("[ReceiveFile] Reading <"+size+"> bytes."); + long start = System.currentTimeMillis(); + ApplicationCode.CopySocketFile(fos, client,size,false); + long end = System.currentTimeMillis(); + double rate=1000.0*size/1024/1024/(end-start); + System.out.println("[ReceiveFile] Rate: "+format.format(rate)+" MBytes/sec. " + +format.format(8*rate)+" MBit/sec."); + System.out.println("接收文件完成:"+rspFile); + client.close(); + + } + catch(Exception ex) + { + + } + finally{ + try { + fos.close(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + }}); + recfile.setDaemon(true); + recfile.setName("文件接收_"+localFile); + recfile.start(); + + }catch(Exception ex){ + throw new RuntimeException(ex); + } + + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ab/506f76f61fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/ab/506f76f61fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..02860bf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ab/506f76f61fac001710ff8a7c6bda0fb8 @@ -0,0 +1,87 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} + +/** + * 整理数据 + * @return + */ +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private boolean isRWMaster=true;//与默认值一致 +private boolean islagerRead=false; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + this.isRWMaster=isRead; + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.islagerRead=islarge; +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ab/b09a89816da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/ab/b09a89816da800171a8482560d609ceb new file mode 100644 index 0000000..9513601 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ab/b09a89816da800171a8482560d609ceb @@ -0,0 +1,35 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFile.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("127.0.0.1", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ac/30abf1fab4ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/30abf1fab4ad0017181ed9113883eda9 new file mode 100644 index 0000000..d42c7af --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/30abf1fab4ad0017181ed9113883eda9 @@ -0,0 +1,187 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.SocketException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.SequenceNumber; + +/** + * Client side of a client-server UDT connection. + * Once established, the session provides a valid {@link UDTSocket}. + */ +public class ClientSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private UDPEndPoint endPoint; + public volatile int connectNum=0; + public ClientSession(UDPEndPoint endPoint, Destination dest)throws SocketException{ + super("ClientSession localPort="+endPoint.getLocalPort(),dest); + this.endPoint=endPoint; + logger.info("Created "+toString()); + } + + /** + * send connection handshake until a reply from server is received + * TODO check for timeout + * @throws InterruptedException + * @throws IOException + */ + + public void connect() throws InterruptedException,IOException{ + int n=0; + + while(getState()!=ready){ + + sendHandShake(); + if(getState()==invalid)throw new IOException("Can't connect!"); + n++; + if(getState()!=ready)Thread.sleep(500); + } + + cc.init(); + logger.info("Connected, "+n+" handshake packets sent"); + } + + @Override + public void received(UDTPacket packet, Destination peer) { + + lastPacket=packet; + + if (packet instanceof ConnectionHandshake) { + ConnectionHandshake hs=(ConnectionHandshake)packet; + + logger.info("Received connection handshake from "+peer+"\n"+hs); + + if (getState()!=ready) { + if(hs.getConnectionType()==1){ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + sendConfirmation(hs); + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + else{ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + setState(ready); + Thread.sleep(50); + this.setInitialSequenceNumber(hs.getInitialSeqNo());//cd 必须重置 + System.out.println("初始序列置回2:"+this.getInitialSequenceNumber()); + socket=new UDTSocket(endPoint,this); + + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + } + } + + if(getState() == ready) { + + if(packet instanceof Shutdown){ + setState(shutdown); + active=false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + active = true; + try{ + if(packet.forSender()){ + socket.getSender().receive(lastPacket); + }else{ + socket.getReceiver().receive(lastPacket); + } + }catch(Exception ex){ + //session is invalid + logger.log(Level.SEVERE,"Error in "+toString(),ex); + setState(invalid); + } + return; + } + } + + + //handshake for connect + protected void sendHandShake()throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(ConnectionHandshake.CONNECTION_TYPE_REGULAR); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + long initialSequenceNo=SequenceNumber.random(); + setInitialSequenceNumber(initialSequenceNo); + handshake.setInitialSeqNo(initialSequenceNo); + handshake.setPacketSize(getDatagramSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending "+handshake); + endPoint.doSend(handshake); + } + + //2nd handshake for connect + protected void sendConfirmation(ConnectionHandshake hs)throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(-1); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + handshake.setInitialSeqNo(hs.getInitialSeqNo()); + handshake.setPacketSize(hs.getPacketSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending confirmation "+handshake); + endPoint.doSend(handshake); + } + + + public UDTPacket getLastPkt(){ + return lastPacket; + } + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ac/805f8d8db5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/805f8d8db5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..1014f4d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/805f8d8db5ac001716b9ca6d5abb90bc @@ -0,0 +1,355 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.PacketFactory; +import udt.util.UDTThreadFactory; + +/** + * the UDPEndpoint takes care of sending and receiving UDP network packets, + * dispatching them to the correct {@link UDTSession} + */ +public class UDPEndPoint { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private final int port; + + private final DatagramSocket dgSocket; + + //active sessions keyed by socket ID + private final Mapsessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + logger.log(Level.INFO, "接受数据: "+packet.getPacketSequenceNumber()); + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&stopped) + { + //已经正常关闭 + } + else + { + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + } + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ac/a0ca04a35ba800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/a0ca04a35ba800171a8482560d609ceb new file mode 100644 index 0000000..ac9ea61 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/a0ca04a35ba800171a8482560d609ceb @@ -0,0 +1,196 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }) + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ad/40667fc262a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/ad/40667fc262a800171a8482560d609ceb new file mode 100644 index 0000000..2fdf3a6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ad/40667fc262a800171a8482560d609ceb @@ -0,0 +1,16 @@ +/** + * + */ +package judp; + +/** + * @author jinyu + * + */ +public class judpGroupSocket { + +public judpGroupSocket() +{ + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ad/4083114ddeac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/ad/4083114ddeac001716b9ca6d5abb90bc new file mode 100644 index 0000000..5b6b3aa --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ad/4083114ddeac001716b9ca6d5abb90bc @@ -0,0 +1,179 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long startTime=System.currentTimeMillis(); + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=sumBytes/((System.currentTimeMillis()-startTime)/1000); + + log.info("文件接收速度:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ad/70fcec3e27ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/ad/70fcec3e27ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..58dd9c8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ad/70fcec3e27ac001710ff8a7c6bda0fb8 @@ -0,0 +1,337 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sub.split(data, dataLen); + } + for(int i=0;i list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + i=-1;//重新遍历 + index=i; + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + //cd 添加 + + + + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/af/0088a7b1c9ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/af/0088a7b1c9ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..8bbaa68 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/af/0088a7b1c9ac001716b9ca6d5abb90bc @@ -0,0 +1,605 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ControlPacket; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.packets.Shutdown; +import udt.packets.ControlPacket.ControlPacketType; +import udt.receiver.AckHistoryEntry; +import udt.receiver.AckHistoryWindow; +import udt.receiver.PacketHistoryWindow; +import udt.receiver.PacketPairWindow; +import udt.receiver.ReceiverLossList; +import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + +/** + * receiver part of a UDT entity + * @see UDTSender + */ +public class UDTReceiver { + + private static final Logger logger=Logger.getLogger(UDTReceiver.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //record seqNo of detected lostdata and latest feedback time + private final ReceiverLossList receiverLossList; + + //record each sent ACK and the sent time + private final AckHistoryWindow ackHistoryWindow; + + //Packet history window that stores the time interval between the current and the last seq. + private final PacketHistoryWindow packetHistoryWindow; + + //for storing the arrival time of the last received data packet + private volatile long lastDataPacketArrivalTime=0; + + //largest received data packet sequence number(LRSN) + private volatile long largestReceivedSeqNumber=0; + + //ACK event related + + //last Ack number + private long lastAckNumber=0; + + //largest Ack number ever acknowledged by ACK2 + private volatile long largestAcknowledgedAckNumber=-1; + + //EXP event related + + //a variable to record number of continuous EXP time-out events + private volatile long expCount=0; + + /*records the time interval between each probing pair + compute the median packet pair interval of the last + 16 packet pair intervals (PI) and the estimate link capacity.(packet/s)*/ + private final PacketPairWindow packetPairWindow; + + //estimated link capacity + long estimateLinkCapacity; + // the packet arrival rate + long packetArrivalSpeed; + + //round trip time, calculated from ACK/ACK2 pairs + long roundTripTime=0; + //round trip time variance + long roundTripTimeVar=roundTripTime/2; + + //to check the ACK, NAK, or EXP timer + private long nextACK; + //microseconds to next ACK event + private long ackTimerInterval=Util.getSYNTime(); + + private long nextNAK; + //microseconds to next NAK event + private long nakTimerInterval=Util.getSYNTime(); + + private long nextEXP; + //microseconds to next EXP event + private long expTimerInterval=100*Util.getSYNTime(); + + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + + //buffer size for storing data + private final long bufferSize; + + //stores received packets to be sent + private final BlockingQueuehandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + logger.info("haveNewData:失败"); + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + logger.info("largestReceivedSeqNumber:"+largestReceivedSeqNumber); + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/af/308465da1bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/af/308465da1bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..303cadc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/af/308465da1bac001710ff8a7c6bda0fb8 @@ -0,0 +1,26 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public static void addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(); + hash.put(id, struct); + } + struct.addData(data); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/af/b087283700ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/af/b087283700ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b/30f2f53008ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b/30f2f53008ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..5205b29 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b/30f2f53008ac001710ff8a7c6bda0fb8 @@ -0,0 +1,98 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; + +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + @SuppressWarnings("rawtypes") + private final ReferenceQueue q = new ReferenceQueue(); + private long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b/700303e004ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b/700303e004ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..335644e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b/700303e004ac001710ff8a7c6bda0fb8 @@ -0,0 +1,32 @@ +/** + * + */ +package judp; + + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + public SocketReference(judpSocket socket, long socketID2, ReferenceQueue q) { + // TODO Auto-generated constructor stub + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b/806d1b51b4ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/b/806d1b51b4ad0017181ed9113883eda9 new file mode 100644 index 0000000..3fd2f0f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b/806d1b51b4ad0017181ed9113883eda9 @@ -0,0 +1,524 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b/9082330aa0ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/b/9082330aa0ad0017181ed9113883eda9 new file mode 100644 index 0000000..e60097a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b/9082330aa0ad0017181ed9113883eda9 @@ -0,0 +1,33 @@ +/** + * + */ +package net.File; + +import java.io.File; +import java.io.StringReader; + +import javax.swing.text.Document; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.xml.sax.InputSource; + +/** + * @author jinyu + * + */ +public class ReadXml { +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder=factory.newDocumentBuilder(); + Document doc = (Document) builder.parse(is); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b/c059b6a503ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b/c059b6a503ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..92f4bf0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b/c059b6a503ac001710ff8a7c6bda0fb8 @@ -0,0 +1,77 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference objsocket=q.poll(); + if(objsocket.get()!=null) + { + judpSocket socket=objsocket.get(); + if(socket.getCloseState()) + { + + socket.close(); + } + } + + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b0/70d2168260a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/b0/70d2168260a800171a8482560d609ceb new file mode 100644 index 0000000..2f32423 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b0/70d2168260a800171a8482560d609ceb @@ -0,0 +1,262 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import udt.util.ReceiveBuffer; + +/** + * The UDTInputStream receives data blocks from the {@link UDTSocket} + * as they become available, and places them into an ordered, + * bounded queue (the flow window) for reading by the application + * + * + */ +public class UDTInputStream extends InputStream { + + //the socket owning this inputstream + private final UDTSocket socket; + + private final ReceiveBuffer receiveBuffer; + + //set to 'false' by the receiver when it gets a shutdown signal from the peer + //see the noMoreData() method + private final AtomicBoolean expectMoreData=new AtomicBoolean(true); + + private volatile boolean closed=false; + + private volatile boolean blocking=true; + + private volatile boolean hasData=false;//cd + + + + /** + * create a new {@link UDTInputStream} connected to the given socket + * @param socket - the {@link UDTSocket} + * @throws IOException + */ + public UDTInputStream(UDTSocket socket)throws IOException{ + this.socket=socket; + int capacity=socket!=null? 2 * socket.getSession().getFlowWindowSize() : 128 ; + long initialSequenceNum=socket!=null?socket.getSession().getInitialSequenceNumber():1; + receiveBuffer=new ReceiveBuffer(capacity,initialSequenceNum); + } + + private final byte[]single=new byte[1]; + + @Override + public int read()throws IOException{ + int b=0; + while(b==0) + b=read(single); + + if(b>0){ + return single[0]; + } + else { + return b; + } + } + + private AppData currentChunk=null; + //offset into currentChunk + int offset=0; + long id=-1; + @Override + public int read(byte[]target)throws IOException{ + try{ + int read=0; + updateCurrentChunk(false); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(blocking && read==0); + } + + if(read>0)return read; + if(closed)return -1; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; + //no more data + return -1; + + }catch(Exception ex){ + IOException e= new IOException(); + e.initCause(ex); + throw e; + } + } + + /** + * Reads the next valid chunk of application data from the queue
+ * + * In blocking mode,this method will block until data is available or the socket is closed, + * otherwise it will wait for at most 10 milliseconds. + * + * @throws InterruptedException + */ + private void updateCurrentChunk(boolean block)throws IOException{ + if(currentChunk!=null)return; + + while(true){ + try{ + if(block){ + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); + while (!closed && currentChunk==null){ + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); + } + } + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); + + }catch(InterruptedException ie){ + IOException ex=new IOException(); + ex.initCause(ie); + throw ex; + } + return; + } + } + + /** + * new application data + * @param data + * + */ + protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + return receiveBuffer.offer(new AppData(sequenceNumber,data)); + } + + @Override + public void close()throws IOException{ + if(closed)return; + closed=true; + noMoreData(); + } + + public UDTSocket getSocket(){ + return socket; + } + + /** + * sets the blocking mode + * @param block + */ + public void setBlocking(boolean block){ + this.blocking=block; + } + + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + + /** + * notify the input stream that there is no more data + * @throws IOException + */ + protected void noMoreData()throws IOException{ + expectMoreData.set(false); + } + + /** + * used for storing application data and the associated + * sequence number in the queue in ascending order + */ + public static class AppData implements Comparable{ + final long sequenceNumber; + final byte[] data; + public AppData(long sequenceNumber, byte[]data){ + this.sequenceNumber=sequenceNumber; + this.data=data; + } + + @Override + public int compareTo(AppData o) { + return (int)(sequenceNumber-o.sequenceNumber); + } + + @Override + public String toString(){ + return sequenceNumber+"["+data.length+"]"; + } + + public long getSequenceNumber(){ + return sequenceNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + public boolean isHasData() + { + + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b1/0051cea6d5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b1/0051cea6d5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..f405083 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b1/0051cea6d5ac001716b9ca6d5abb90bc @@ -0,0 +1,263 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b1/504219b51dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b1/504219b51dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..6f9a5fe --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b1/504219b51dac001710ff8a7c6bda0fb8 @@ -0,0 +1,63 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + int index=0; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b1/d074365422ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b1/d074365422ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..903398a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b1/d074365422ac001710ff8a7c6bda0fb8 @@ -0,0 +1,208 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=client.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; + } + public int read(byte[]data) + { + try { + return client.read(data); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return -1; + } + public void close() + { + if(client!=null) + { + if(sumLen==0) + { + //没有发送数据 + //立即关闭 + try { + if(!client.isClose()) + client.shutdown(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + else + { + //开始缓存 + //SocketManager.getInstance().add(client); + if(!client.isClose()) + client.close(); + } + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b1/f0e13d3e5ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/b1/f0e13d3e5ca800171a8482560d609ceb new file mode 100644 index 0000000..4b8d7dd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b1/f0e13d3e5ca800171a8482560d609ceb @@ -0,0 +1,207 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + } + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b2/204ab9a023ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b2/204ab9a023ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..9818ccd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b2/204ab9a023ac001710ff8a7c6bda0fb8 @@ -0,0 +1,316 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + + return false; +} +/** + * 获取远端host + * @return + */ +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} + +/** + * 获取远端端口 + * @return + */ +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} + +/** + * socketid + * @return + */ +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b2/b0190bb66aa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/b2/b0190bb66aa800171a8482560d609ceb new file mode 100644 index 0000000..85d3a72 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b2/b0190bb66aa800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * + */ +package Test; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; +import net.File.SendFiles; + + + +/** + * @author jinyu + * + */ +public class TestSendFile { + private static Logger log=Logger.getLogger(TestSendFile.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + SendFiles send=new SendFiles("127.0.0.1", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b2/d07c71886da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/b2/d07c71886da800171a8482560d609ceb new file mode 100644 index 0000000..35194ca --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b2/d07c71886da800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFile.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + SendFiles send=new SendFiles("127.0.0.1", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b3/201bd76bb3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/201bd76bb3ad0017181ed9113883eda9 new file mode 100644 index 0000000..2d89569 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/201bd76bb3ad0017181ed9113883eda9 @@ -0,0 +1,511 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b3/40a5f1e8b8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/40a5f1e8b8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..ef04afe --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/40a5f1e8b8ac001716b9ca6d5abb90bc @@ -0,0 +1,603 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ControlPacket; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.packets.Shutdown; +import udt.packets.ControlPacket.ControlPacketType; +import udt.receiver.AckHistoryEntry; +import udt.receiver.AckHistoryWindow; +import udt.receiver.PacketHistoryWindow; +import udt.receiver.PacketPairWindow; +import udt.receiver.ReceiverLossList; +import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + +/** + * receiver part of a UDT entity + * @see UDTSender + */ +public class UDTReceiver { + + private static final Logger logger=Logger.getLogger(UDTReceiver.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //record seqNo of detected lostdata and latest feedback time + private final ReceiverLossList receiverLossList; + + //record each sent ACK and the sent time + private final AckHistoryWindow ackHistoryWindow; + + //Packet history window that stores the time interval between the current and the last seq. + private final PacketHistoryWindow packetHistoryWindow; + + //for storing the arrival time of the last received data packet + private volatile long lastDataPacketArrivalTime=0; + + //largest received data packet sequence number(LRSN) + private volatile long largestReceivedSeqNumber=0; + + //ACK event related + + //last Ack number + private long lastAckNumber=0; + + //largest Ack number ever acknowledged by ACK2 + private volatile long largestAcknowledgedAckNumber=-1; + + //EXP event related + + //a variable to record number of continuous EXP time-out events + private volatile long expCount=0; + + /*records the time interval between each probing pair + compute the median packet pair interval of the last + 16 packet pair intervals (PI) and the estimate link capacity.(packet/s)*/ + private final PacketPairWindow packetPairWindow; + + //estimated link capacity + long estimateLinkCapacity; + // the packet arrival rate + long packetArrivalSpeed; + + //round trip time, calculated from ACK/ACK2 pairs + long roundTripTime=0; + //round trip time variance + long roundTripTimeVar=roundTripTime/2; + + //to check the ACK, NAK, or EXP timer + private long nextACK; + //microseconds to next ACK event + private long ackTimerInterval=Util.getSYNTime(); + + private long nextNAK; + //microseconds to next NAK event + private long nakTimerInterval=Util.getSYNTime(); + + private long nextEXP; + //microseconds to next EXP event + private long expTimerInterval=100*Util.getSYNTime(); + + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + + //buffer size for storing data + private final long bufferSize; + + //stores received packets to be sent + private final BlockingQueuehandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + logger.info("sendNAK:"+currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b3/80ea2f8de7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/80ea2f8de7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..5fa122b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/80ea2f8de7ac001716b9ca6d5abb90bc @@ -0,0 +1,36 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //192.168.30.128 + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("127.0.0.1", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b3/90c2fce664a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/90c2fce664a800171a8482560d609ceb new file mode 100644 index 0000000..93da029 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/90c2fce664a800171a8482560d609ceb @@ -0,0 +1,50 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b4/30eed20e64a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/b4/30eed20e64a800171a8482560d609ceb new file mode 100644 index 0000000..f43cc67 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b4/30eed20e64a800171a8482560d609ceb @@ -0,0 +1,27 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private ConcurrentHashMap hash=new ConcurrentHashMap(); +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b4/d047883de1ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b4/d047883de1ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..570f876 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b4/d047883de1ac001716b9ca6d5abb90bc @@ -0,0 +1,188 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-lastTime)/1000); + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b4/e0ac193f65a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/b4/e0ac193f65a800171a8482560d609ceb new file mode 100644 index 0000000..347b1f5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b4/e0ac193f65a800171a8482560d609ceb @@ -0,0 +1,64 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + + for(Map entryr:hash.keySet()) + { + + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b5/40399e4003ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b5/40399e4003ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..40f1f58 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b5/40399e4003ac001710ff8a7c6bda0fb8 @@ -0,0 +1,21 @@ +/** + * + */ +package judp; + + +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + + public SocketReference(T referent) { + super(referent); + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b5/90f32a02b3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/b5/90f32a02b3ad0017181ed9113883eda9 new file mode 100644 index 0000000..71c0dcf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b5/90f32a02b3ad0017181ed9113883eda9 @@ -0,0 +1,502 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b5/c0de2650ccac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b5/c0de2650ccac001716b9ca6d5abb90bc new file mode 100644 index 0000000..14a4e85 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b5/c0de2650ccac001716b9ca6d5abb90bc @@ -0,0 +1,199 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isReadMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + public void resetBufMaster(boolean isRead) + { + this.isReadMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b6/80a6bd9bb6ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/b6/80a6bd9bb6ad0017181ed9113883eda9 new file mode 100644 index 0000000..430de6b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b6/80a6bd9bb6ad0017181ed9113883eda9 @@ -0,0 +1,524 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s0) + { + + if(lastAckSequenceNumber/10000!=ackNumber/10000) + { + client.connectNum--; + //修正 + //ackNumber 特别大,则会全部删除,特别小,一个都不会删除 + if(lastAckSequenceNumberthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + } + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b6/c08c15e6cbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b6/c08c15e6cbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..5874ac9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b6/c08c15e6cbac001716b9ca6d5abb90bc @@ -0,0 +1,193 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + /** + * 清除重复检验 + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/30d491dd37ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/30d491dd37ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ea5c983 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/30d491dd37ac001710ff8a7c6bda0fb8 @@ -0,0 +1,100 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i0?1:0); + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(len); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/8099f407b8ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/8099f407b8ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..5c588a6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/8099f407b8ac001716b9ca6d5abb90bc @@ -0,0 +1,600 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ControlPacket; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.packets.Shutdown; +import udt.packets.ControlPacket.ControlPacketType; +import udt.receiver.AckHistoryEntry; +import udt.receiver.AckHistoryWindow; +import udt.receiver.PacketHistoryWindow; +import udt.receiver.PacketPairWindow; +import udt.receiver.ReceiverLossList; +import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + +/** + * receiver part of a UDT entity + * @see UDTSender + */ +public class UDTReceiver { + + private static final Logger logger=Logger.getLogger(UDTReceiver.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //record seqNo of detected lostdata and latest feedback time + private final ReceiverLossList receiverLossList; + + //record each sent ACK and the sent time + private final AckHistoryWindow ackHistoryWindow; + + //Packet history window that stores the time interval between the current and the last seq. + private final PacketHistoryWindow packetHistoryWindow; + + //for storing the arrival time of the last received data packet + private volatile long lastDataPacketArrivalTime=0; + + //largest received data packet sequence number(LRSN) + private volatile long largestReceivedSeqNumber=0; + + //ACK event related + + //last Ack number + private long lastAckNumber=0; + + //largest Ack number ever acknowledged by ACK2 + private volatile long largestAcknowledgedAckNumber=-1; + + //EXP event related + + //a variable to record number of continuous EXP time-out events + private volatile long expCount=0; + + /*records the time interval between each probing pair + compute the median packet pair interval of the last + 16 packet pair intervals (PI) and the estimate link capacity.(packet/s)*/ + private final PacketPairWindow packetPairWindow; + + //estimated link capacity + long estimateLinkCapacity; + // the packet arrival rate + long packetArrivalSpeed; + + //round trip time, calculated from ACK/ACK2 pairs + long roundTripTime=0; + //round trip time variance + long roundTripTimeVar=roundTripTime/2; + + //to check the ACK, NAK, or EXP timer + private long nextACK; + //microseconds to next ACK event + private long ackTimerInterval=Util.getSYNTime(); + + private long nextNAK; + //microseconds to next NAK event + private long nakTimerInterval=Util.getSYNTime(); + + private long nextEXP; + //microseconds to next EXP event + private long expTimerInterval=100*Util.getSYNTime(); + + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + + //buffer size for storing data + private final long bufferSize; + + //stores received packets to be sent + private final BlockingQueuehandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/902ed8cecbad00171b48cedc605eece5 b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/902ed8cecbad00171b48cedc605eece5 new file mode 100644 index 0000000..2f8c41a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/902ed8cecbad00171b48cedc605eece5 @@ -0,0 +1,52 @@ +/** + * + */ +package net.File; + +import java.io.File; +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + + ReadXml rd=new ReadXml(); + String xml= rd.readXml(ReadXml.getPath()+"/Config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + SendFiles send=new SendFiles(config[0], Integer.valueOf(config[1])); + FilesWatch watch=new FilesWatch(); + String dir=config[2]; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/c0821a2b23ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/c0821a2b23ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..2888d26 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/c0821a2b23ac001710ff8a7c6bda0fb8 @@ -0,0 +1,234 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + + byte[][]sendData= PackagetSub.split(data); + try { + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b8/504716dd52ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/504716dd52ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..99e19ad --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/504716dd52ac001710ff8a7c6bda0fb8 @@ -0,0 +1,150 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i20) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b8/601c95a8d7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/601c95a8d7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..e30080a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/601c95a8d7ac001716b9ca6d5abb90bc @@ -0,0 +1,142 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + receiveBuffer.resetBufMaster(isRead); + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + receiveBuffer.setLargeRead(islarge); +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b8/f048c24722ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/f048c24722ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..eb162f9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/f048c24722ac001710ff8a7c6bda0fb8 @@ -0,0 +1,208 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; + } + public int read(byte[]data) + { + try { + return client.read(data); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return -1; + } + public void close() + { + if(client!=null) + { + if(sumLen==0) + { + //没有发送数据 + //立即关闭 + try { + if(!client.isClose()) + client.shutdown(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + else + { + //开始缓存 + //SocketManager.getInstance().add(client); + if(!client.isClose()) + client.close(); + } + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b9/10c10c5969a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/10c10c5969a800171a8482560d609ceb new file mode 100644 index 0000000..38a5570 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/10c10c5969a800171a8482560d609ceb @@ -0,0 +1,112 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + //judpSocket jsocket=new judpSocket(csocket); + sessionHandoff.put(jsocket); + SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ +try { + judpSocket jsocket= sessionHandoff.take(); + return jsocket; +} catch (InterruptedException e) { + logger.info("judpSocket接收中断:"+e.getMessage()); + e.printStackTrace(); +} +return null; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b9/50671825d4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/50671825d4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..6a39656 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/50671825d4ac001716b9ca6d5abb90bc @@ -0,0 +1,246 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b9/60d8a6a904ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/60d8a6a904ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ac22c2c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/60d8a6a904ac001710ff8a7c6bda0fb8 @@ -0,0 +1,91 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b9/705e0ff7e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/705e0ff7e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..56c1ad0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/705e0ff7e4ac001716b9ca6d5abb90bc @@ -0,0 +1,234 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b9/70ab9f9451ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/70ab9f9451ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..dd870d7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/70ab9f9451ac001710ff8a7c6bda0fb8 @@ -0,0 +1,150 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i20) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else + { + break; + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b9/80aea1e1e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/80aea1e1e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..7ba4b79 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/80aea1e1e4ac001716b9ca6d5abb90bc @@ -0,0 +1,236 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + ss.close(); + break; + } + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b9/90260fc76da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/90260fc76da800171a8482560d609ceb new file mode 100644 index 0000000..41b9514 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/90260fc76da800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * 文件名:TestRecFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpRecviceFile; + +/** + * + * 项目名称:judp + * 类名称:TestRecFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:42 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:42 + * 修改备注: + * @version + * + */ +public class TestRecFile { + + public static void main(String[] args) { + judpRecviceFile rec=new judpRecviceFile("127.0.0.1", 5555, "E:\\Study\\java\\filesudt\\send\\12.rmvb", "E:\\Study\\java\\filesudt\\rec\\1.rmvb"); + rec.start(); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ba/509862f704ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/509862f704ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..785f0a1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/509862f704ac001710ff8a7c6bda0fb8 @@ -0,0 +1,33 @@ +/** + * + */ +package judp; + + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + public SocketReference(T referent, long socketID2, ReferenceQueue q) { + super(referent,q); + this.socketid=id; + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ba/607e6669b5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/607e6669b5ad0017181ed9113883eda9 new file mode 100644 index 0000000..be94d73 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/607e6669b5ad0017181ed9113883eda9 @@ -0,0 +1,523 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s0) + { + client.connectNum--; + if(lastAckSequenceNumber/10000!=ackNumber/10000) + { + //修正 + //ackNumber 特别大,则会全部删除,特别小,一个都不会删除 + if(lastAckSequenceNumberthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + } + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ba/60fa14012cac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/60fa14012cac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..6275295 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/60fa14012cac001710ff8a7c6bda0fb8 @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int sumNum=0; +private volatile int sumLen=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} + +/** + * 整理数据 + * @return + */ +private boolean check() +{ + if(sumNum>=buffer.length) + { + //检查成功 + if(sumLen==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ +try { + UDTSocket socket=SocketControls.getInstance().getSocket(); + judpSocket jsocket=new judpSocket(socket); + //judpSocket jsocket= sessionHandoff.take(); + return jsocket; +} catch (InterruptedException e) { + logger.info("judpSocket接收中断:"+e.getMessage()); + e.printStackTrace(); +} +return null; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ba/d0d925c01bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/d0d925c01bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..d1a03ce --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/d0d925c01bac001710ff8a7c6bda0fb8 @@ -0,0 +1,27 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public static void addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int index=buf.getInt(); + int dataLen=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(); + hash.put(id, struct); + } +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bb/20b3f7a44fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/bb/20b3f7a44fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..8087586 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bb/20b3f7a44fac001710ff8a7c6bda0fb8 @@ -0,0 +1,243 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + //cd + long ackNumber=acknowledgement.getAckNumber(); + // cd + if(this.session instanceof ClientSession) + { + //cd + if(this.isModify) + { + //已经发送过10000包,不用再修正,认为接收方已经关闭 + if(bufferNum<10000) + { + if(ackNumber/10000!=this.session.getInitialSequenceNumber()/10000) + { + //认为不同段的seqNo,则不是通信的接收方session + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + return; + } + } + else + { + this.isModify=false;//不用再修正 + } + } + } + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bb/d05f6666dbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/bb/d05f6666dbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..1b5f8c8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bb/d05f6666dbac001716b9ca6d5abb90bc @@ -0,0 +1,368 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +//private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + // readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } + + return result; +} + + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bd/0092f91127ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/bd/0092f91127ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..fd870c1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bd/0092f91127ac001710ff8a7c6bda0fb8 @@ -0,0 +1,327 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=PackagetSub.split(data); + for(int i=0;i + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + public SocketReference(T referent, long socketID2, ReferenceQueue q) { + super(referent); + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bd/606102f529ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/bd/606102f529ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c44e916 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bd/606102f529ac001710ff8a7c6bda0fb8 @@ -0,0 +1,100 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i0){ + return single[0]; + } + else { + return b; + } + } + + private AppData currentChunk=null; + //offset into currentChunk + int offset=0; + long id=-1; + @Override + public int read(byte[]target)throws IOException{ + try{ + int read=0; + updateCurrentChunk(false); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(blocking && read==0); + } + + if(read>0)return read; + if(closed)return -1; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; + //no more data + return -1; + + }catch(Exception ex){ + IOException e= new IOException(); + e.initCause(ex); + throw e; + } + } + + /** + * Reads the next valid chunk of application data from the queue
+ * + * In blocking mode,this method will block until data is available or the socket is closed, + * otherwise it will wait for at most 10 milliseconds. + * + * @throws InterruptedException + */ + private void updateCurrentChunk(boolean block)throws IOException{ + if(currentChunk!=null)return; + + while(true){ + try{ + if(block){ + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); + while (!closed && currentChunk==null){ + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); + } + } + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); + + }catch(InterruptedException ie){ + IOException ex=new IOException(); + ex.initCause(ie); + throw ex; + } + return; + } + } + + /** + * new application data + * @param data + * + */ + protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + hasData=true; + return receiveBuffer.offer(new AppData(sequenceNumber,data)); + } + + @Override + public void close()throws IOException{ + if(closed)return; + closed=true; + noMoreData(); + } + + public UDTSocket getSocket(){ + return socket; + } + + /** + * sets the blocking mode + * @param block + */ + public void setBlocking(boolean block){ + this.blocking=block; + } + + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + + /** + * notify the input stream that there is no more data + * @throws IOException + */ + protected void noMoreData()throws IOException{ + expectMoreData.set(false); + } + + /** + * 判断有没有数据进来 + * cd + * @return + */ + public boolean isHasData() + { + return hasData; + } + + /** + * used for storing application data and the associated + * sequence number in the queue in ascending order + */ + public static class AppData implements Comparable{ + final long sequenceNumber; + final byte[] data; + public AppData(long sequenceNumber, byte[]data){ + this.sequenceNumber=sequenceNumber; + this.data=data; + } + + @Override + public int compareTo(AppData o) { + return (int)(sequenceNumber-o.sequenceNumber); + } + + @Override + public String toString(){ + return sequenceNumber+"["+data.length+"]"; + } + + public long getSequenceNumber(){ + return sequenceNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bd/d0a4982c03ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/bd/d0a4982c03ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f2b2a40 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bd/d0a4982c03ac001710ff8a7c6bda0fb8 @@ -0,0 +1,21 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + + public SocketReference(T referent) { + super(referent); + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/be/809095536aa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/be/809095536aa800171a8482560d609ceb new file mode 100644 index 0000000..c577d9f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/be/809095536aa800171a8482560d609ceb @@ -0,0 +1,16 @@ +/** + * + */ +package net.File; + + +import java.nio.file.WatchEvent.Kind; + +/** + * @author jinyu + * + */ +public class FileMonitor { +public String file; +public Kind kind; +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/be/f0170dbcb5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/be/f0170dbcb5ad0017181ed9113883eda9 new file mode 100644 index 0000000..be94d73 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/be/f0170dbcb5ad0017181ed9113883eda9 @@ -0,0 +1,523 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s0) + { + client.connectNum--; + if(lastAckSequenceNumber/10000!=ackNumber/10000) + { + //修正 + //ackNumber 特别大,则会全部删除,特别小,一个都不会删除 + if(lastAckSequenceNumberthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + } + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bf/707a9cdbc4ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/bf/707a9cdbc4ad0017181ed9113883eda9 new file mode 100644 index 0000000..27fb903 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bf/707a9cdbc4ad0017181ed9113883eda9 @@ -0,0 +1,509 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + if(this.isModify) + { + if(bufferNum<10000) + { + if(ackNumber/10000!=this.session.getInitialSequenceNumber()/10000) + { + return; + } + } + } + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bf/80cced3d64a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/bf/80cced3d64a800171a8482560d609ceb new file mode 100644 index 0000000..471417f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bf/80cced3d64a800171a8482560d609ceb @@ -0,0 +1,27 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private ConcurrentHashMap hash=new ConcurrentHashMap(); +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bf/90cc8e0637ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/bf/90cc8e0637ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c0df784 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bf/90cc8e0637ac001710ff8a7c6bda0fb8 @@ -0,0 +1,100 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c0/100a598904ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/100a598904ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..a6db6e8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/100a598904ac001710ff8a7c6bda0fb8 @@ -0,0 +1,86 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.info("清除session:"+ex.getMessage()); + } + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c0/4069778be0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/4069778be0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..6b8fb1d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/4069778be0ac001716b9ca6d5abb90bc @@ -0,0 +1,149 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + + } + long end=System.currentTimeMillis(); + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()+",平均速度:"+); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c0/90fe4f592dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/90fe4f592dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..1fa20a8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/90fe4f592dac001710ff8a7c6bda0fb8 @@ -0,0 +1,100 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c0/f05994565ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/f05994565ca800171a8482560d609ceb new file mode 100644 index 0000000..4100ef8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/f05994565ca800171a8482560d609ceb @@ -0,0 +1,223 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + } + if(closeThread.isAlive()) + { + return; + } + esle + { + closeThread.start(); + } + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c1/1026fc199fad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/c1/1026fc199fad0017181ed9113883eda9 new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c1/409b84a8cfac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/c1/409b84a8cfac001716b9ca6d5abb90bc new file mode 100644 index 0000000..02b4380 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c1/409b84a8cfac001716b9ca6d5abb90bc @@ -0,0 +1,232 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 + if(highestReadSequenceNumber+1100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + long endTime=System.currentTimeMillis(); + client.close(); + dis.close(); + long speed=fLen/((endTime-startTime)/1000); + log.info("发送完成:"+f.getName()+",平均速度(M/S):"+speed/1024/1024); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c1/b02fa6c104ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c1/b02fa6c104ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..e46e9eb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c1/b02fa6c104ac001710ff8a7c6bda0fb8 @@ -0,0 +1,87 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c1/e00d35ec5fac00171ca19969f19d2325 b/.metadata/.plugins/org.eclipse.core.resources/.history/c1/e00d35ec5fac00171ca19969f19d2325 new file mode 100644 index 0000000..07c9a04 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c1/e00d35ec5fac00171ca19969f19d2325 @@ -0,0 +1,237 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.concurrent.TimeUnit; + +import udt.packets.DataPacket; + +/** + * UDTSocket is analogous to a normal java.net.Socket, it provides input and + * output streams for the application + * + * TODO is it possible to actually extend java.net.Socket ? + * + * + */ +public class UDTSocket { + //一个session对应一个udtsocket + //endpoint + private final UDPEndPoint endpoint; + + private volatile boolean active; + + private volatile boolean close=false;//关闭标识,cd + + //processing received data + private UDTReceiver receiver; + private UDTSender sender; + + private final UDTSession session; + + private UDTInputStream inputStream; + private UDTOutputStream outputStream; + + /** + * @param host + * @param port + * @param endpoint + * @throws SocketException,UnknownHostException + */ + public UDTSocket(UDPEndPoint endpoint, UDTSession session)throws SocketException,UnknownHostException{ + this.endpoint=endpoint; + this.session=session; + this.receiver=new UDTReceiver(session,endpoint); + this.sender=new UDTSender(session,endpoint); + } + + public UDTReceiver getReceiver() { + return receiver; + } + + public void setReceiver(UDTReceiver receiver) { + this.receiver = receiver; + } + + public UDTSender getSender() { + return sender; + } + + public void setSender(UDTSender sender) { + this.sender = sender; + } + + public void setActive(boolean active) { + this.active = active; + } + + public boolean isActive() { + return active; + } + + public UDPEndPoint getEndpoint() { + return endpoint; + } + + public boolean isClose() + { + return close; + } + /** + * get the input stream for reading from this socket + * @return + */ + public synchronized UDTInputStream getInputStream()throws IOException{ + if(inputStream==null){ + inputStream=new UDTInputStream(this); + } + return inputStream; + } + + /** + * get the output stream for writing to this socket + * @return + */ + public synchronized UDTOutputStream getOutputStream(){ + if(outputStream==null){ + outputStream=new UDTOutputStream(this); + } + return outputStream; + } + + public final UDTSession getSession(){ + return session; + } + + /** + * write single block of data without waiting for any acknowledgement + * @param data + */ + protected void doWrite(byte[]data)throws IOException{ + doWrite(data, 0, data.length); + + } + + /** + * write the given data + * @param data - the data array + * @param offset - the offset into the array + * @param length - the number of bytes to write + * @throws IOException + */ + protected void doWrite(byte[]data, int offset, int length)throws IOException{ + try{ + doWrite(data, offset, length, Integer.MAX_VALUE, TimeUnit.MILLISECONDS); + }catch(InterruptedException ie){ + IOException io=new IOException(); + io.initCause(ie); + throw io; + } + } + + /** + * write the given data, waiting at most for the specified time if the queue is full + * @param data + * @param offset + * @param length + * @param timeout + * @param units + * @throws IOException - if data cannot be sent + * @throws InterruptedException + */ + protected void doWrite(byte[]data, int offset, int length, int timeout, TimeUnit units)throws IOException,InterruptedException{ + int chunksize=session.getDatagramSize()-24;//need some bytes for the header + ByteBuffer bb=ByteBuffer.wrap(data,offset,length); + long seqNo=0; + while(bb.remaining()>0){ + int len=Math.min(bb.remaining(),chunksize); + byte[]chunk=new byte[len]; + bb.get(chunk); + DataPacket packet=new DataPacket(); + seqNo=sender.getNextSequenceNumber(); + packet.setPacketSequenceNumber(seqNo); + packet.setSession(session); + packet.setDestinationID(session.getDestination().getSocketID()); + packet.setData(chunk); + System.out.println("sender sendUdtPacket1"); + //put the packet into the send queue + if(!sender.sendUdtPacket(packet, timeout, units)){ + throw new IOException("Queue full"); + } + System.out.println("sender sendUdtPacket2"); + } + if(length>0)active=true; + System.out.println("sender sendUdtPacket out"); + } + /** + * will block until the outstanding packets have really been sent out + * and acknowledged + */ + protected void flush() throws InterruptedException{ + if(!active)return; + final long seqNo=sender.getCurrentSequenceNumber(); + if(seqNo<0)throw new IllegalStateException(); + while(!sender.isSentOut(seqNo)){ + Thread.sleep(5); + } + if(seqNo>-1){ + //wait until data has been sent out and acknowledged + while(active && !sender.haveAcknowledgementFor(seqNo)){ + sender.waitForAck(seqNo); + } + } + //TODO need to check if we can pause the sender... + //sender.pause(); + } + + //writes and wait for ack + protected void doWriteBlocking(byte[]data)throws IOException, InterruptedException{ + doWrite(data); + flush(); + } + + /** + * close the connection + * @throws IOException + */ + public void close()throws IOException{ + if(inputStream!=null)inputStream.close(); + if(outputStream!=null)outputStream.close(); + active=false; + close=true; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c2/0011b739e0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/0011b739e0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..a9f0b3c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/0011b739e0ac001716b9ca6d5abb90bc @@ -0,0 +1,148 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c2/50701c5f06ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/50701c5f06ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..01cf916 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/50701c5f06ac001710ff8a7c6bda0fb8 @@ -0,0 +1,120 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c2/805d9d5d1eac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/805d9d5d1eac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..d5ad971 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/805d9d5d1eac001710ff8a7c6bda0fb8 @@ -0,0 +1,28 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public DataStruct addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + struct.addData(data); + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c2/b069017f11ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/b069017f11ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..894b554 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/b069017f11ac001710ff8a7c6bda0fb8 @@ -0,0 +1,27 @@ +package Test; + +import java.util.concurrent.TimeUnit; + +import judp.judpClient; + +public class TestClient { + + public static void main(String[] args) { + while(true) + { + judpClient client=new judpClient(); + client.connect("127.0.0.1", 5555); + byte[]data=("hello word "+System.currentTimeMillis()).getBytes(); + client.sendData(data); + client.close(); + try { + System.out.println("等待"); + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c2/e0564af81dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/e0564af81dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..09b5aa0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c2/e0564af81dac001710ff8a7c6bda0fb8 @@ -0,0 +1,78 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} + +/** + * 整理数据 + * @return + */ +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + if(highestReadSequenceNumber+1 fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/timespan/1000; + sumBytes=0; + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c3/e05862c8afad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/c3/e05862c8afad0017181ed9113883eda9 new file mode 100644 index 0000000..71c0dcf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c3/e05862c8afad0017181ed9113883eda9 @@ -0,0 +1,502 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c4/20419ed021ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/20419ed021ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..44662c2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/20419ed021ac001710ff8a7c6bda0fb8 @@ -0,0 +1,50 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); + private ConcurrentLinkedQueue queue=new ConcurrentLinkedQueue(); + + /** + * 添加数据 + * @param data + * @return + */ +public boolean addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + boolean r= struct.addData(data); + if(r) + { + byte[]result =struct.getData(); + byte[] tmp=new byte[result.length]; + System.arraycopy(result, 0, tmp, 0, tmp.length); + queue.offer(tmp); + struct.clear(); + hash.remove(id); + } + return r; + +} +public byte[] getData() +{ + return queue.poll(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c4/70c215f856ac00171c63d91e40f02a62 b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/70c215f856ac00171c63d91e40f02a62 new file mode 100644 index 0000000..aa49956 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/70c215f856ac00171c63d91e40f02a62 @@ -0,0 +1,152 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c4/c01a91c731ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/c01a91c731ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..d269039 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/c01a91c731ac001710ff8a7c6bda0fb8 @@ -0,0 +1,338 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(getCloseState()) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i queue=new LinkedBlockingQueue(); + private boolean isStop=false; + public FilesWatch() + { + try { + watcher = FileSystems.getDefault().newWatchService(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + public void setWatch(String dir) + { + this.dir=dir; + } + public void stop() + { + isStop=true; + } + public FileMonitor take() + { + try { + return queue.take(); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + return null; + } + public void start() + { + checkThread =new Thread(new Runnable() { + + @Override + public void run() { + try + { + Paths.get(dir).register(watcher, + StandardWatchEventKinds.ENTRY_CREATE, + StandardWatchEventKinds.ENTRY_DELETE, + StandardWatchEventKinds.ENTRY_MODIFY); + } + catch(Exception ex) + { + + } + while (!isStop) { + WatchKey key; + try { + key = watcher.take(); + for (WatchEvent event: key.pollEvents()) { + FileMonitor e=new FileMonitor(); + e.file=event.context().toString(); + e.kind=event.kind(); + queue.put(e); + } + + boolean valid = key.reset(); + if (!valid) { + break; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + + + }); + checkThread.setDaemon(true); + checkThread.setName("monitor"); + checkThread.start(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c6/000d73ae31ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c6/000d73ae31ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..22dde28 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c6/000d73ae31ac001710ff8a7c6bda0fb8 @@ -0,0 +1,338 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(!this.isRWMaster) + { + //写入为主时,数据就直接覆盖了 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c6/30d1f210f7ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c6/30d1f210f7ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f0b7103 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c6/30d1f210f7ab001710ff8a7c6bda0fb8 @@ -0,0 +1,120 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + for(int i=0;ihandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c7/303bbd9222ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/c7/303bbd9222ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..5411aa9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c7/303bbd9222ac001710ff8a7c6bda0fb8 @@ -0,0 +1,208 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(client.isClose()) + { + return null; + } + r=client.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; + } + public int read(byte[]data) + { + try { + return client.read(data); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return -1; + } + public void close() + { + if(client!=null) + { + if(sumLen==0) + { + //没有发送数据 + //立即关闭 + try { + if(!client.isClose()) + client.shutdown(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + else + { + //开始缓存 + //SocketManager.getInstance().add(client); + if(!client.isClose()) + client.close(); + } + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c7/306b6cb061ac00171ca19969f19d2325 b/.metadata/.plugins/org.eclipse.core.resources/.history/c7/306b6cb061ac00171ca19969f19d2325 new file mode 100644 index 0000000..f2fe99c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c7/306b6cb061ac00171ca19969f19d2325 @@ -0,0 +1,155 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + TimeUnit.SECONDS.sleep(1); + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c7/50f07caf6aa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/c7/50f07caf6aa800171a8482560d609ceb new file mode 100644 index 0000000..cba6941 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c7/50f07caf6aa800171a8482560d609ceb @@ -0,0 +1,35 @@ +/** + * + */ +package Test; + +import java.io.IOException; +import java.util.logging.Logger; + +import net.File.RecviceFiles; + + +/** + * @author jinyu + * + */ +public class TestRecFile { + private static Logger log=Logger.getLogger(TestRecFile.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + RecviceFiles rec=new RecviceFiles(); + String dir="F://dbfile"; + rec.setDir(dir); + rec.start("127.0.0.1", 5555); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c8/30cbde246aa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/c8/30cbde246aa800171a8482560d609ceb new file mode 100644 index 0000000..495a637 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c8/30cbde246aa800171a8482560d609ceb @@ -0,0 +1,104 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + + if(readPosition==size) + {readPosition=0; + if(this.islagerRead) + { + clearDeHash(this.size-leftNum); + } + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ca/f04c3ce267a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/ca/f04c3ce267a800171a8482560d609ceb new file mode 100644 index 0000000..58a8069 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ca/f04c3ce267a800171a8482560d609ceb @@ -0,0 +1,77 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + i=-1;//重新遍历 + index=i; + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getSession(). + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cb/20fd1e9c05ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/cb/20fd1e9c05ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..791d171 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cb/20fd1e9c05ac001710ff8a7c6bda0fb8 @@ -0,0 +1,92 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除session:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cb/500f92514fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/cb/500f92514fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..eaf6ad5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cb/500f92514fac001710ff8a7c6bda0fb8 @@ -0,0 +1,132 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=20*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + + } + long endTime=System.currentTimeMillis(); + client.close(); + dis.close(); + long speed=fLen/((endTime-startTime)/1000); + log.info("发送完成:"+f.getName()+",平均速度(M/S):"+speed/1024/1024); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cb/f0426ab665a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/cb/f0426ab665a800171a8482560d609ceb new file mode 100644 index 0000000..a5081dc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cb/f0426ab665a800171a8482560d609ceb @@ -0,0 +1,33 @@ +/** + * + */ +package judp; + +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} +public judpGroupSocket getSocket() +{ + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cc/20526809d6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/20526809d6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..df405f4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/20526809d6ac001716b9ca6d5abb90bc @@ -0,0 +1,274 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cc/908cb5595ba800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/908cb5595ba800171a8482560d609ceb new file mode 100644 index 0000000..ca547c9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/908cb5595ba800171a8482560d609ceb @@ -0,0 +1,183 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10s + */ + public synchronized void close() + { + + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cc/b06dd99a19ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/b06dd99a19ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..71ddaef --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/b06dd99a19ac001710ff8a7c6bda0fb8 @@ -0,0 +1,73 @@ +/** + * + */ +package judp; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong subid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + public byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-DataHead.headLen; + } + long session=sessionid.incrementAndGet(); + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + DataHead head=new DataHead(session,data.length,(byte) 0); + + for(int i=0;i=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/timespan/1000; + } + else + { + //不到1s + } + speed=sumBytes/(()/1000); + } + catch(Exception ex) + { + + } + lastTime=System.currentTimeMillis(); + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ce/10663a33dbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/ce/10663a33dbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..9432304 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ce/10663a33dbac001716b9ca6d5abb90bc @@ -0,0 +1,605 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ControlPacket; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.packets.Shutdown; +import udt.packets.ControlPacket.ControlPacketType; +import udt.receiver.AckHistoryEntry; +import udt.receiver.AckHistoryWindow; +import udt.receiver.PacketHistoryWindow; +import udt.receiver.PacketPairWindow; +import udt.receiver.ReceiverLossList; +import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + +/** + * receiver part of a UDT entity + * @see UDTSender + */ +public class UDTReceiver { + + private static final Logger logger=Logger.getLogger(UDTReceiver.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //record seqNo of detected lostdata and latest feedback time + private final ReceiverLossList receiverLossList; + + //record each sent ACK and the sent time + private final AckHistoryWindow ackHistoryWindow; + + //Packet history window that stores the time interval between the current and the last seq. + private final PacketHistoryWindow packetHistoryWindow; + + //for storing the arrival time of the last received data packet + private volatile long lastDataPacketArrivalTime=0; + + //largest received data packet sequence number(LRSN) + private volatile long largestReceivedSeqNumber=0; + + //ACK event related + + //last Ack number + private long lastAckNumber=0; + + //largest Ack number ever acknowledged by ACK2 + private volatile long largestAcknowledgedAckNumber=-1; + + //EXP event related + + //a variable to record number of continuous EXP time-out events + private volatile long expCount=0; + + /*records the time interval between each probing pair + compute the median packet pair interval of the last + 16 packet pair intervals (PI) and the estimate link capacity.(packet/s)*/ + private final PacketPairWindow packetPairWindow; + + //estimated link capacity + long estimateLinkCapacity; + // the packet arrival rate + long packetArrivalSpeed; + + //round trip time, calculated from ACK/ACK2 pairs + long roundTripTime=0; + //round trip time variance + long roundTripTimeVar=roundTripTime/2; + + //to check the ACK, NAK, or EXP timer + private long nextACK; + //microseconds to next ACK event + private long ackTimerInterval=Util.getSYNTime(); + + private long nextNAK; + //microseconds to next NAK event + private long nakTimerInterval=Util.getSYNTime(); + + private long nextEXP; + //microseconds to next EXP event + private long expTimerInterval=100*Util.getSYNTime(); + + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + + //buffer size for storing data + private final long bufferSize; + + //stores received packets to be sent + private final BlockingQueuehandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + logger.info("largestReceivedSeqNumber:"+largestReceivedSeqNumber); + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ce/80357b80dfad00171536fea4e2c2e8be b/.metadata/.plugins/org.eclipse.core.resources/.history/ce/80357b80dfad00171536fea4e2c2e8be new file mode 100644 index 0000000..1c167f9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ce/80357b80dfad00171536fea4e2c2e8be @@ -0,0 +1,523 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cf/407ed953c3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/cf/407ed953c3ad0017181ed9113883eda9 new file mode 100644 index 0000000..e98f7bb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cf/407ed953c3ad0017181ed9113883eda9 @@ -0,0 +1,493 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d0/4051a3aee0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/d0/4051a3aee0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..b1668d4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d0/4051a3aee0ac001716b9ca6d5abb90bc @@ -0,0 +1,150 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + + } + long end=System.currentTimeMillis(); + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()+",平均速度:"+); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d0/605e9939b5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/d0/605e9939b5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..1b170e5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d0/605e9939b5ac001716b9ca6d5abb90bc @@ -0,0 +1,355 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.PacketFactory; +import udt.util.UDTThreadFactory; + +/** + * the UDPEndpoint takes care of sending and receiving UDP network packets, + * dispatching them to the correct {@link UDTSession} + */ +public class UDPEndPoint { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private final int port; + + private final DatagramSocket dgSocket; + + //active sessions keyed by socket ID + private final Mapsessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + logger.log(Level.INFO, "接受数据: "+packet.getPacketSequenceNumber());; + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&stopped) + { + //已经正常关闭 + } + else + { + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + } + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d0/80a9ccb923ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d0/80a9ccb923ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..5917b29 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d0/80a9ccb923ac001710ff8a7c6bda0fb8 @@ -0,0 +1,320 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=PackagetSub.split(data); + for(int i=0;i hash=new ConcurrentHashMap(); +// private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + for(int i=0;i hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) +// { +// //比当前发送包都大,修正 cd +// lastAckSequenceNumber=ackNumber; +// } + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d2/40fe2bd9d5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/d2/40fe2bd9d5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..7fe262a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d2/40fe2bd9d5ac001716b9ca6d5abb90bc @@ -0,0 +1,265 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d2/7022b67821ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d2/7022b67821ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..0e84b09 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d2/7022b67821ac001710ff8a7c6bda0fb8 @@ -0,0 +1,290 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private long start=System.currentTimeMillis(); +private boolean isClose=false; +private long readLen=0;//读取数据 +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private static final Logger logger=Logger.getLogger(judpSocket.class.getName()); +private PackagetCombin pack=new PackagetCombin(); +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + + +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + flushTime=System.currentTimeMillis(); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d2/70c87e2e6aa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/d2/70c87e2e6aa800171a8482560d609ceb new file mode 100644 index 0000000..1fbeb78 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d2/70c87e2e6aa800171a8482560d609ceb @@ -0,0 +1,104 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +// private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;i hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }) + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d3/302bfa4709ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d3/302bfa4709ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..5b17470 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d3/302bfa4709ac001710ff8a7c6bda0fb8 @@ -0,0 +1,100 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.util.HashMap; +import java.util.WeakHashMap; + +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + @SuppressWarnings("rawtypes") + private final ReferenceQueue q = new ReferenceQueue(); + private volatile long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private final HashMap,Long> map=new HashMap,Long> (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + map.put(tmp, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d3/403ff763c5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/d3/403ff763c5ad0017181ed9113883eda9 new file mode 100644 index 0000000..3b2da96 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d3/403ff763c5ad0017181ed9113883eda9 @@ -0,0 +1,522 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d3/f093a187a2ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/d3/f093a187a2ad0017181ed9113883eda9 new file mode 100644 index 0000000..0e78749 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d3/f093a187a2ad0017181ed9113883eda9 @@ -0,0 +1,79 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * @author jinyu + * + */ +public class ReadXml { +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Document doc = null; + try { + doc = (Document) builder.parse(is); + } catch (SAXException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + NodeList list=doc.getElementsByTagName("IP"); + String ip= list.item(0).getTextContent(); + list=doc.getElementsByTagName("Port"); + String port=list.item(0).getTextContent(); + list=doc.getElementsByTagName("Dir"); + String dir=list.item(0).getTextContent(); + String strxml=ip+","+port+","+dir; + return strxml; + } +private String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d4/40c49ebde0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/d4/40c49ebde0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..0f2d6d4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d4/40c49ebde0ac001716b9ca6d5abb90bc @@ -0,0 +1,150 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + + } + long endTime=System.currentTimeMillis(); + client.close(); + dis.close(); + long speed=fLen/((endTime-startTime)/1000); + log.info("发送完成:"+f.getName()+",平均速度(M/S):"+speed/1024/1024); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d4/d0f62a8bf7ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d4/d0f62a8bf7ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7ebe20f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d4/d0f62a8bf7ab001710ff8a7c6bda0fb8 @@ -0,0 +1,83 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + index=i; + i=-1;//重新遍历 + + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d5/0093b68423ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/0093b68423ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7a3eb7b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/0093b68423ac001710ff8a7c6bda0fb8 @@ -0,0 +1,322 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + try { + + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +/** + * 获取远端host + * @return + */ +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} + +/** + * 获取远端端口 + * @return + */ +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} + +/** + * socketid + * @return + */ +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d5/20908afcb3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/20908afcb3ad0017181ed9113883eda9 new file mode 100644 index 0000000..e26ca3e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/20908afcb3ad0017181ed9113883eda9 @@ -0,0 +1,515 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + + } + + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d5/30a55330acac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/30a55330acac001716b9ca6d5abb90bc new file mode 100644 index 0000000..b8a71dd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/30a55330acac001716b9ca6d5abb90bc @@ -0,0 +1,155 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=8*65535; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d5/40cbe317ccac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/40cbe317ccac001716b9ca6d5abb90bc new file mode 100644 index 0000000..915604d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/40cbe317ccac001716b9ca6d5abb90bc @@ -0,0 +1,193 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isReadMaster=true; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + /** + * 清除重复检验 + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d5/50968f281cac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/50968f281cac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..fed315a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/50968f281cac001710ff8a7c6bda0fb8 @@ -0,0 +1,32 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] data; +public long id; +public DataStruct(int num) +{ + data=new byte[num][]; +} +public void addData(byte[]data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + int index=buf.getInt(); + dataLen=buf.getInt(); + byte[] tmp=new byte[buf.limit()-buf.position()]; + buf.get(tmp); + data[index]=tmp; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b09d47221cac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b09d47221cac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..8b4dab8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b09d47221cac001710ff8a7c6bda0fb8 @@ -0,0 +1,28 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] data; +public long id; +public DataStruct(int num) +{ + data=new byte[num][]; +} +public void addData(byte[]data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + int index=buf.getInt(); + dataLen=buf.getInt(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d7/004317ff64a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/d7/004317ff64a800171a8482560d609ceb new file mode 100644 index 0000000..0f87dc0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d7/004317ff64a800171a8482560d609ceb @@ -0,0 +1,59 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }); + + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d7/60d73d281dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d7/60d73d281dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..d0eeb67 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d7/60d73d281dac001710ff8a7c6bda0fb8 @@ -0,0 +1,53 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + for(int i=0;isessions=new ConcurrentHashMap(); + + //last received packet + private UDTPacket lastPacket; + + //if the endpoint is configured for a server socket, + //this queue is used to handoff new UDTSessions to the application + private final SynchronousQueue sessionHandoff=new SynchronousQueue(); + + private boolean serverSocketMode=false; + + //has the endpoint been stopped? + private volatile boolean stopped=false; + + public static final int DATAGRAM_SIZE=1400; + + private volatile int sessionnum=0;//cd 添加 临时统计 + + /** + * create an endpoint on the given socket + * + * @param socket - a UDP datagram socket + */ + public UDPEndPoint(DatagramSocket socket){ + this.dgSocket=socket; + port=dgSocket.getLocalPort(); + } + + /** + * bind to any local port on the given host address + * @param localAddress + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress)throws SocketException, UnknownHostException{ + this(localAddress,0); + } + + /** + * Bind to the given address and port + * @param localAddress + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(InetAddress localAddress, int localPort)throws SocketException, UnknownHostException{ + if(localAddress==null){ + dgSocket=new DatagramSocket(localPort, localAddress); + }else{ + dgSocket=new DatagramSocket(localPort); + } + if(localPort>0)this.port = localPort; + else port=dgSocket.getLocalPort(); + + //set a time out to avoid blocking in doReceive() + dgSocket.setSoTimeout(100000); + //buffer size + dgSocket.setReceiveBufferSize(128*1024); + } + + /** + * bind to the default network interface on the machine + * + * @param localPort - the port to bind to. If the port is zero, the system will pick an ephemeral port. + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint(int localPort)throws SocketException, UnknownHostException{ + this(null,localPort); + } + + /** + * bind to an ephemeral port on the default network interface on the machine + * + * @throws SocketException + * @throws UnknownHostException + */ + public UDPEndPoint()throws SocketException, UnknownHostException{ + this(null,0); + } + + /** + * start the endpoint. If the serverSocketModeEnabled flag is true, + * a new connection can be handed off to an application. The application needs to + * call #accept() to get the socket + * @param serverSocketModeEnabled + */ + public void start(boolean serverSocketModeEnabled){ + serverSocketMode=serverSocketModeEnabled; + //start receive thread + Runnable receive=new Runnable(){ + @Override + public void run(){ + try{ + doReceive(); + }catch(Exception ex){ + logger.log(Level.WARNING,"",ex); + } + } + }; + Thread t=UDTThreadFactory.get().newThread(receive); + t.setDaemon(true); + t.start(); + logger.info("UDTEndpoint started."); + } + + public void start(){ + start(false); + } + + public void stop(){ + stopped=true; + dgSocket.close(); + } + + /** + * @return the port which this client is bound to + */ + public int getLocalPort() { + return this.dgSocket.getLocalPort(); + } + /** + * @return Gets the local address to which the socket is bound + */ + public InetAddress getLocalAddress(){ + return this.dgSocket.getLocalAddress(); + } + + DatagramSocket getSocket(){ + return dgSocket; + } + + UDTPacket getLastPacket(){ + return lastPacket; + } + + public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); + sessionnum++; + sessions.put(destinationID, session); + } + + public UDTSession getSession(Long destinationID){ + return sessions.get(destinationID); + } + + /** + * 移除session + * cd + * @param socketid + * @return + */ + public UDTSession removeSession(long socketid) + { + //cd + sessionnum--; + logger.info("Storing Sessionnum:"+sessionnum); + return sessions.remove(socketid); + } + public Collection getSessions(){ + return sessions.values(); + } + + /** + * wait the given time for a new connection + * @param timeout - the time to wait + * @param unit - the {@link TimeUnit} + * @return a new {@link UDTSession} + * @throws InterruptedException + */ + protected UDTSession accept(long timeout, TimeUnit unit)throws InterruptedException{ + return sessionHandoff.poll(timeout, unit); + } + + + final DatagramPacket dp= new DatagramPacket(new byte[DATAGRAM_SIZE],DATAGRAM_SIZE); + + /** + * single receive, run in the receiverThread, see {@link #start()} + *
    + *
  • Receives UDP packets from the network
  • + *
  • Converts them to UDT packets
  • + *
  • dispatches the UDT packets according to their destination ID.
  • + *
+ * @throws IOException + */ + private long lastDestID=-1; + private UDTSession lastSession; + + //MeanValue v=new MeanValue("receiver processing ",true, 256); + + private int n=0; + + private final Object lock=new Object(); + + protected void doReceive()throws IOException{ + while(!stopped){ + try{ + try{ + //v.end(); + + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + //v.begin(); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; + + //handle connection handshake + if(packet.isConnectionHandshake()){ + synchronized(lock){ + Long id=Long.valueOf(packet.getDestinationID()); + UDTSession session=sessions.get(id); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } + } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); + } + } + else{ + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + n++; + if(n%100==1){ + logger.warning("Unknown session <"+dest+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + } + else{ + session.received(packet,peer); + logger.log(Level.INFO, "接受数据: "+packet.getPacketSequenceNumber()); + } + } + }catch(SocketException ex){ + if(ex.getMessage().equals("socket closed")&&stopped) + { + //已经正常关闭 + } + else + { + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + } + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped + } + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); + } + } + } + + protected void doSend(UDTPacket packet)throws IOException{ + byte[]data=packet.getEncoded(); + DatagramPacket dgp = packet.getSession().getDatagram(); + dgp.setData(data); + dgSocket.send(dgp); + } + + @Override + public String toString(){ + return "UDPEndpoint port="+port; + } + + public void sendRaw(DatagramPacket p)throws IOException{ + dgSocket.send(p); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d7/f0ad1fce60ac00171ca19969f19d2325 b/.metadata/.plugins/org.eclipse.core.resources/.history/d7/f0ad1fce60ac00171ca19969f19d2325 new file mode 100644 index 0000000..4c5925c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d7/f0ad1fce60ac00171ca19969f19d2325 @@ -0,0 +1,248 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + System.out.println("sendBlocking start"); + client.sendBlocking(data); + r=data.length; + sumLen+=r; + System.out.println("sendBlocking end"); + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i20) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,infobytes.length,PackagetCharSet.CharSet); + if(!serverinfp.equals("initServer:"+f.getName())) + { + client.close(); + return; + } + //client.decreNum(); + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + //ByteBuffer buffer=ByteBuffer.wrap(buf); + + while((count=dis.read(buf,0, bufSize))!=-1) + { + if(count==bufSize) + { + client.sendData(buf); + } + else + { + byte[] tmp=new byte[count+name.length+4]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + } + + } + client.close(); + dis.close(); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d8/f00b8baa06ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d8/f00b8baa06ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..01bcb6b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d8/f00b8baa06ac001710ff8a7c6bda0fb8 @@ -0,0 +1,34 @@ +/** + * + */ +package judp; + + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + @SuppressWarnings("rawtypes") + public SocketReference(T referent, long id, ReferenceQueue q) { + super(referent,q); + this.socketid=id; + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d8/f05963bc23ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d8/f05963bc23ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7cc0510 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d8/f05963bc23ac001710ff8a7c6bda0fb8 @@ -0,0 +1,324 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=PackagetSub.split(data); + for(int i=0;isendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d9/b057cfe669a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/d9/b057cfe669a800171a8482560d609ceb new file mode 100644 index 0000000..873fe61 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d9/b057cfe669a800171a8482560d609ceb @@ -0,0 +1,113 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d9/c009708fd7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/d9/c009708fd7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..d830bfb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d9/c009708fd7ac001716b9ca6d5abb90bc @@ -0,0 +1,121 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d9/d0c9f45526ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/d9/d0c9f45526ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..097beec --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d9/d0c9f45526ac001710ff8a7c6bda0fb8 @@ -0,0 +1,89 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;ihandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + logger.info("sendNAK:"+currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + logger.info("sendNAK List:"+sequenceNumbers.size()); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/da/6081ae6d5ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/da/6081ae6d5ca800171a8482560d609ceb new file mode 100644 index 0000000..b5ce008 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/da/6081ae6d5ca800171a8482560d609ceb @@ -0,0 +1,225 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/da/c0eefdc32aad001713e0de43c08806fd b/.metadata/.plugins/org.eclipse.core.resources/.history/da/c0eefdc32aad001713e0de43c08806fd new file mode 100644 index 0000000..1756b26 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/da/c0eefdc32aad001713e0de43c08806fd @@ -0,0 +1,189 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.SocketException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.SequenceNumber; + +/** + * Client side of a client-server UDT connection. + * Once established, the session provides a valid {@link UDTSocket}. + */ +public class ClientSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); + + private UDPEndPoint endPoint; + + public ClientSession(UDPEndPoint endPoint, Destination dest)throws SocketException{ + super("ClientSession localPort="+endPoint.getLocalPort(),dest); + this.endPoint=endPoint; + logger.info("Created "+toString()); + } + + /** + * send connection handshake until a reply from server is received + * TODO check for timeout + * @throws InterruptedException + * @throws IOException + */ + + public void connect() throws InterruptedException,IOException{ + int n=0; + + while(getState()!=ready){ + + sendHandShake(); + if(getState()==invalid)throw new IOException("Can't connect!"); + n++; + if(getState()!=ready)Thread.sleep(500); + } + + cc.init(); + logger.info("Connected, "+n+" handshake packets sent"); + } + + @Override + public void received(UDTPacket packet, Destination peer) { + + lastPacket=packet; + + if (packet instanceof ConnectionHandshake) { + ConnectionHandshake hs=(ConnectionHandshake)packet; + + logger.info("Received connection handshake from "+peer+"\n"+hs); + + if (getState()!=ready) { + if(hs.getConnectionType()==1){ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + sendConfirmation(hs); + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + else{ + try{ + //TODO validate parameters sent by peer + long peerSocketID=hs.getSocketID(); + destination.setSocketID(peerSocketID); + setState(ready); + Thread.sleep(50); + logger.info("初始序列置回:"+hs.getInitialSeqNo()); + this.setInitialSequenceNumber(hs.getInitialSeqNo());//cd 必须重置 + socket=new UDTSocket(endPoint,this); + + + }catch(Exception ex){ + logger.log(Level.WARNING,"Error creating socket",ex); + setState(invalid); + } + return; + } + } + } + + if(getState() == ready) { + + if(packet instanceof Shutdown){ + setState(shutdown); + active=false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + active = true; + try{ + if(packet.forSender()){ + socket.getSender().receive(lastPacket); + }else{ + socket.getReceiver().receive(lastPacket); + } + }catch(Exception ex){ + //session is invalid + logger.log(Level.SEVERE,"Error in "+toString(),ex); + setState(invalid); + } + return; + } + } + + + //handshake for connect + protected void sendHandShake()throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(ConnectionHandshake.CONNECTION_TYPE_REGULAR); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + long initialSequenceNo=SequenceNumber.random(); + setInitialSequenceNumber(initialSequenceNo); + handshake.setInitialSeqNo(initialSequenceNo); + handshake.setPacketSize(getDatagramSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending "+handshake); + endPoint.doSend(handshake); + } + + //2nd handshake for connect + protected void sendConfirmation(ConnectionHandshake hs)throws IOException{ + ConnectionHandshake handshake = new ConnectionHandshake(); + handshake.setConnectionType(-1); + handshake.setSocketType(ConnectionHandshake.SOCKET_TYPE_DGRAM); + handshake.setInitialSeqNo(hs.getInitialSeqNo()); + handshake.setPacketSize(hs.getPacketSize()); + handshake.setSocketID(mySocketID); + handshake.setMaxFlowWndSize(flowWindowSize); + handshake.setSession(this); + logger.info("Sending confirmation "+handshake); + endPoint.doSend(handshake); + } + + + public UDTPacket getLastPkt(){ + return lastPacket; + } + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/db/d05d7acd7fad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/db/d05d7acd7fad0017181ed9113883eda9 new file mode 100644 index 0000000..289fd07 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/db/d05d7acd7fad0017181ed9113883eda9 @@ -0,0 +1,191 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.KeepAlive; +import udt.packets.Shutdown; + +/** + * server side session in client-server mode + */ +public class ServerSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ServerSession.class.getName()); + + private final UDPEndPoint endPoint; + + //last received packet (for testing purposes) + private UDTPacket lastPacket; + + + public ServerSession(DatagramPacket dp, UDPEndPoint endPoint)throws SocketException,UnknownHostException{ + super("ServerSession localPort="+endPoint.getLocalPort()+" peer="+dp.getAddress()+":"+dp.getPort(),new Destination(dp.getAddress(),dp.getPort())); + this.endPoint=endPoint; + logger.info("Created "+toString()+" talking to "+dp.getAddress()+":"+dp.getPort()); + } + + int n_handshake=0; + + @Override + public void received(UDTPacket packet, Destination peer){ + lastPacket=packet; + + if(packet instanceof ConnectionHandshake) { + ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; + logger.info("Received "+connectionHandshake); + + if (getState()<=ready){ + destination.setSocketID(connectionHandshake.getSocketID()); + this.endPoint.addSession(destination.getSocketID(), this.mySocketID); + if(getState()<=handshaking){ + setState(handshaking); + } + try{ + handleHandShake(connectionHandshake); + n_handshake++; + try{ + setState(ready); + socket=new UDTSocket(endPoint, this); + cc.init(); + }catch(Exception uhe){ + //session is invalid + logger.log(Level.SEVERE,"",uhe); + setState(invalid); + } + }catch(IOException ex){ + //session invalid + logger.log(Level.WARNING,"Error processing ConnectionHandshake",ex); + setState(invalid); + } + return; + } + + }else if(packet instanceof KeepAlive) { + socket.getReceiver().resetEXPTimer(); + active = true; + return; + } + + if(getState()== ready) { + active = true; + + if (packet instanceof KeepAlive) { + //nothing to do here + return; + }else if (packet instanceof Shutdown) { + try{ + socket.getReceiver().stop(); + }catch(IOException ex){ + logger.log(Level.WARNING,"",ex); + } + setState(shutdown); + System.out.println("SHUTDOWN ***"); + active = false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + + else{ + try{ + + if(packet.forSender()){ + socket.getSender().receive(packet); + }else{ + socket.getReceiver().receive(packet); + } + }catch(Exception ex){ + //session invalid + logger.log(Level.SEVERE,"",ex); + setState(invalid); + } + } + return; + + } + + + } + + /** + * for testing use only + */ + UDTPacket getLastPacket(){ + return lastPacket; + } + + /** + * handle the connection handshake:
+ *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/dc/904dedc619ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/dc/904dedc619ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..762beb5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/dc/904dedc619ac001710ff8a7c6bda0fb8 @@ -0,0 +1,74 @@ +/** + * + */ +package judp; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + DataHead head=new DataHead(session,data.length,(byte) 0); + + for(int i=0;i queue=new LinkedBlockingQueue(); + private boolean isStop=false; + public FilesWatch() + { + try { + watcher = FileSystems.getDefault().newWatchService(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + public void setWatch(String dir) + { + this.dir=dir; + } + public void stop() + { + isStop=true; + } + public FileMonitor take() + { + try { + return queue.take(); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + return null; + } + public void start() + { + checkThread =new Thread(new Runnable() { + + @Override + public void run() { + try + { + Paths.get(dir).register(watcher, + StandardWatchEventKinds.ENTRY_CREATE, + StandardWatchEventKinds.ENTRY_DELETE, + StandardWatchEventKinds.ENTRY_MODIFY); + } + catch(Exception ex) + { + + } + while (!isStop) { + WatchKey key; + try { + key = watcher.take(); + for (WatchEvent event: key.pollEvents()) { + FileMonitor e=new FileMonitor(); + e.file=event.context().toString(); + e.kind=event.kind(); + queue.put(e); + } + + boolean valid = key.reset(); + if (!valid) { + break; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + + + }); + checkThread.setDaemon(true); + checkThread.setName("monitor"); + checkThread.start(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/dd/206f8ef4c4ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/dd/206f8ef4c4ad0017181ed9113883eda9 new file mode 100644 index 0000000..5f6c02e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/dd/206f8ef4c4ad0017181ed9113883eda9 @@ -0,0 +1,516 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/dd/d0aca700e0ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/dd/d0aca700e0ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..b310f92 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/dd/d0aca700e0ac001716b9ca6d5abb90bc @@ -0,0 +1,188 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long startTime=System.currentTimeMillis(); + long lastTime=System.currentTimeMillis(); + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + long speed=0; + try + { + speed=sumBytes/((System.currentTimeMillis()-startTime)/1000); + } + catch(Exception ex) + { + + } + log.info("文件接收速度:"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/de/305d803423ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/de/305d803423ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..6e64d40 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/de/305d803423ac001710ff8a7c6bda0fb8 @@ -0,0 +1,233 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + + byte[][]sendData= PackagetSub.split(data); + for(int i=0;i + *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/df/20d826b6d5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/df/20d826b6d5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..65f9567 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/df/20d826b6d5ac001716b9ca6d5abb90bc @@ -0,0 +1,265 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/df/90ce9028bbac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/df/90ce9028bbac001716b9ca6d5abb90bc new file mode 100644 index 0000000..34a9e41 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/df/90ce9028bbac001716b9ca6d5abb90bc @@ -0,0 +1,604 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ControlPacket; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.packets.Shutdown; +import udt.packets.ControlPacket.ControlPacketType; +import udt.receiver.AckHistoryEntry; +import udt.receiver.AckHistoryWindow; +import udt.receiver.PacketHistoryWindow; +import udt.receiver.PacketPairWindow; +import udt.receiver.ReceiverLossList; +import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + +/** + * receiver part of a UDT entity + * @see UDTSender + */ +public class UDTReceiver { + + private static final Logger logger=Logger.getLogger(UDTReceiver.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //record seqNo of detected lostdata and latest feedback time + private final ReceiverLossList receiverLossList; + + //record each sent ACK and the sent time + private final AckHistoryWindow ackHistoryWindow; + + //Packet history window that stores the time interval between the current and the last seq. + private final PacketHistoryWindow packetHistoryWindow; + + //for storing the arrival time of the last received data packet + private volatile long lastDataPacketArrivalTime=0; + + //largest received data packet sequence number(LRSN) + private volatile long largestReceivedSeqNumber=0; + + //ACK event related + + //last Ack number + private long lastAckNumber=0; + + //largest Ack number ever acknowledged by ACK2 + private volatile long largestAcknowledgedAckNumber=-1; + + //EXP event related + + //a variable to record number of continuous EXP time-out events + private volatile long expCount=0; + + /*records the time interval between each probing pair + compute the median packet pair interval of the last + 16 packet pair intervals (PI) and the estimate link capacity.(packet/s)*/ + private final PacketPairWindow packetPairWindow; + + //estimated link capacity + long estimateLinkCapacity; + // the packet arrival rate + long packetArrivalSpeed; + + //round trip time, calculated from ACK/ACK2 pairs + long roundTripTime=0; + //round trip time variance + long roundTripTimeVar=roundTripTime/2; + + //to check the ACK, NAK, or EXP timer + private long nextACK; + //microseconds to next ACK event + private long ackTimerInterval=Util.getSYNTime(); + + private long nextNAK; + //microseconds to next NAK event + private long nakTimerInterval=Util.getSYNTime(); + + private long nextEXP; + //microseconds to next EXP event + private long expTimerInterval=100*Util.getSYNTime(); + + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + + //buffer size for storing data + private final long bufferSize; + + //stores received packets to be sent + private final BlockingQueuehandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + logger.info("sendNAK:"+currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + logger.info("sendNAK List:"+sequenceNumbers.size()); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/df/e05aea31e5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/df/e05aea31e5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..f9a67c0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/df/e05aea31e5ac001716b9ca6d5abb90bc @@ -0,0 +1,239 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/df/f0a11525b5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/df/f0a11525b5ad0017181ed9113883eda9 new file mode 100644 index 0000000..defd91b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/df/f0a11525b5ad0017181ed9113883eda9 @@ -0,0 +1,518 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e/609b46bf31ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/e/609b46bf31ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..03180e1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e/609b46bf31ac001710ff8a7c6bda0fb8 @@ -0,0 +1,338 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(getCloseState()) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(isClose) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ +try { + UDTSocket socket=SocketControls.getInstance().getSocket(); + //judpSocket jsocket=new judpSocket(csocket); + //judpSocket jsocket= sessionHandoff.take(); + return jsocket; +} catch (InterruptedException e) { + logger.info("judpSocket接收中断:"+e.getMessage()); + e.printStackTrace(); +} +return null; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e1/80a8e68d04ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/e1/80a8e68d04ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..3acb753 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e1/80a8e68d04ac001710ff8a7c6bda0fb8 @@ -0,0 +1,86 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e2/20032dc67fad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/20032dc67fad0017181ed9113883eda9 new file mode 100644 index 0000000..6e4a9a6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/20032dc67fad0017181ed9113883eda9 @@ -0,0 +1,191 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.ConnectionHandshake; +import udt.packets.Destination; +import udt.packets.KeepAlive; +import udt.packets.Shutdown; + +/** + * server side session in client-server mode + */ +public class ServerSession extends UDTSession { + + private static final Logger logger=Logger.getLogger(ServerSession.class.getName()); + + private final UDPEndPoint endPoint; + + //last received packet (for testing purposes) + private UDTPacket lastPacket; + + + public ServerSession(DatagramPacket dp, UDPEndPoint endPoint)throws SocketException,UnknownHostException{ + super("ServerSession localPort="+endPoint.getLocalPort()+" peer="+dp.getAddress()+":"+dp.getPort(),new Destination(dp.getAddress(),dp.getPort())); + this.endPoint=endPoint; + logger.info("Created "+toString()+" talking to "+dp.getAddress()+":"+dp.getPort()); + } + + int n_handshake=0; + + @Override + public void received(UDTPacket packet, Destination peer){ + lastPacket=packet; + + if(packet instanceof ConnectionHandshake) { + ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; + logger.info("Received "+connectionHandshake); + + if (getState()<=ready){ + destination.setSocketID(connectionHandshake.getSocketID()); + + if(getState()<=handshaking){ + setState(handshaking); + } + try{ + handleHandShake(connectionHandshake); + n_handshake++; + try{ + setState(ready); + socket=new UDTSocket(endPoint, this); + cc.init(); + }catch(Exception uhe){ + //session is invalid + logger.log(Level.SEVERE,"",uhe); + setState(invalid); + } + }catch(IOException ex){ + //session invalid + logger.log(Level.WARNING,"Error processing ConnectionHandshake",ex); + setState(invalid); + } + return; + } + + }else if(packet instanceof KeepAlive) { + socket.getReceiver().resetEXPTimer(); + active = true; + return; + } + + if(getState()== ready) { + active = true; + + if (packet instanceof KeepAlive) { + //nothing to do here + return; + }else if (packet instanceof Shutdown) { + try{ + socket.getReceiver().stop(); + }catch(IOException ex){ + logger.log(Level.WARNING,"",ex); + } + setState(shutdown); + System.out.println("SHUTDOWN ***"); + active = false; + logger.info("Connection shutdown initiated by the other side."); + return; + } + + else{ + try{ + + if(packet.forSender()){ + socket.getSender().receive(packet); + }else{ + socket.getReceiver().receive(packet); + } + }catch(Exception ex){ + //session invalid + logger.log(Level.SEVERE,"",ex); + setState(invalid); + } + } + return; + + } + + + } + + /** + * for testing use only + */ + UDTPacket getLastPacket(){ + return lastPacket; + } + + /** + * handle the connection handshake:
+ *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e2/5020156065a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/5020156065a800171a8482560d609ceb new file mode 100644 index 0000000..2d4993d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/5020156065a800171a8482560d609ceb @@ -0,0 +1,67 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + + +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + + for(Entry entry:hash.entrySet()) + { + + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e2/70b70a8cc3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/70b70a8cc3ad0017181ed9113883eda9 new file mode 100644 index 0000000..bab37e1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/70b70a8cc3ad0017181ed9113883eda9 @@ -0,0 +1,493 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e2/f0425b8821ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/f0425b8821ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..1f64add --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/f0425b8821ac001710ff8a7c6bda0fb8 @@ -0,0 +1,287 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + + +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + flushTime=System.currentTimeMillis(); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e4/4059f899d9ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/e4/4059f899d9ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..dff1e79 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e4/4059f899d9ac001716b9ca6d5abb90bc @@ -0,0 +1,155 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + while((count=dis.read(buf,0, bufSize))!=-1) + { + log.info("发送数据1:"); + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + log.info("发送数据:"+sum); + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e5/203d7a7234ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/e5/203d7a7234ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..a92c305 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e5/203d7a7234ac001710ff8a7c6bda0fb8 @@ -0,0 +1,338 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public int dataLen=0; +public boolean getCloseState() +{ + //底层已经关闭 + return isClose|socket.isClose(); +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(getCloseState()) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readALL() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(getCloseState()) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(getCloseState()) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 分包发送数据 + * 会再次分割数据,同时添加头 + * 对应的要用readALL + * @param data + * @return + */ +public boolean sendSplitData(byte[]data) { + if(getCloseState()) + { + return false; + } + byte[][]result=null; + if(dataLen==0) + { + result= PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + result=sub.split(data, dataLen); + } + for(int i=0;i hash=new ConcurrentHashMap(); +public static void addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + struct.addData(data); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e5/f0935d6167a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/e5/f0935d6167a800171a8482560d609ceb new file mode 100644 index 0000000..9d527a9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e5/f0935d6167a800171a8482560d609ceb @@ -0,0 +1,66 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + UDTSocket find=null; + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(find==null) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关闭 + find=list.get(i); + i=-1;//重新遍历 + } + } + else + { + // + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e6/207e4997a3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/e6/207e4997a3ad0017181ed9113883eda9 new file mode 100644 index 0000000..efd7ce7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e6/207e4997a3ad0017181ed9113883eda9 @@ -0,0 +1,218 @@ +/** + * 文件名:judpSendFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package judp; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileChannel.MapMode; +import java.text.NumberFormat; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import udt.UDTReceiver; + + +/** + * + * 项目名称:judp + * 类名称:judpSendFile + * 类描述: 文件发送 + * 创建人:jinyu + * 创建时间:2017年8月27日 下午4:30:42 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午4:30:42 + * 修改备注: + * @version + * + */ +public class judpSendFile { + private final int serverPort; + private final String host; + //TODO configure pool size + // private final ExecutorService threadPool=Executors.newFixedThreadPool(3); + private final ExecutorService threadPool=Executors.newCachedThreadPool(); + public judpSendFile(int serverPort){ + this.serverPort=serverPort; + this.host=null; + + } + public judpSendFile(String localIP,int serverPort){ + this.serverPort=serverPort; + this.host=localIP; + + } + + + public void startSend() + { + threadPool.execute(new Runnable() { + @Override + public void run(){ + try{ + UDTReceiver.connectionExpiryDisabled=true; + judpServer server=null; + if(host==null) + { + server=new judpServer(serverPort); + } + else + { + server=new judpServer(host,serverPort); + } + server.start(); + while(true){ + judpSocket socket=server.accept(); + Thread.sleep(1000); + threadPool.execute(new RequestRunner(socket)); + } + }catch(Exception ex){ + throw new RuntimeException(ex); + } + }} + ); + } + + + public static void usage(){ + System.out.println("Usage: java -cp ... udt.util.SendFile " + + "[--verbose] [--localPort=] [--localIP=]"); + } + + public static class RequestRunner implements Runnable{ + + private final static Logger logger=Logger.getLogger(RequestRunner.class.getName()); + + private final judpSocket socket; + + private final NumberFormat format=NumberFormat.getNumberInstance(); + + private final boolean memMapped; + + private boolean verbose; + public RequestRunner(judpSocket socket){ + this.socket=socket; + format.setMaximumFractionDigits(3); + memMapped=false;//true; + } + + @Override + public void run(){ + try{ + logger.info("Handling request from "+socket.getDestination()); + + // UDTInputStream in=socket.getInputStream(); + // UDTOutputStream out=socket.getOutputStream(); + byte[]readBuf=new byte[32768]; + ByteBuffer bb=ByteBuffer.wrap(readBuf); + + //read file name info + int r=0; + while(true) + { + r=socket.readData(readBuf); + if(r==0) + Thread.sleep(100); + else + { + break; + } + } + if(r==-1) + { + socket.close(); + return; + } + //how many bytes to read for the file name + byte[]len=new byte[4]; + bb.get(len); + if(verbose){ + StringBuilder sb=new StringBuilder(); + for(int i=0;i=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + for(int i=0;i hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取; + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size) + {readPosition=0; + clearDeHash(this.size-leftNum); + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e8/20b1cad36ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/20b1cad36ca800171a8482560d609ceb new file mode 100644 index 0000000..e78d13a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/20b1cad36ca800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * 文件名:TestRecFile.java + * + * 版本信息: + * 日期:2017年8月27日 + * Copyright 足下 Corporation 2017 + * 版权所有 + * + */ +package Test; + +import java.io.IOException; + +import judp.judpRecviceFile; + +/** + * + * 项目名称:judp + * 类名称:TestRecFile + * 类描述: + * 创建人:jinyu + * 创建时间:2017年8月27日 下午6:32:42 + * 修改人:jinyu + * 修改时间:2017年8月27日 下午6:32:42 + * 修改备注: + * @version + * + */ +public class TestRecFile { + + public static void main(String[] args) { + judpRecviceFile rec=new judpRecviceFile("192.168.10.86", 5555, "E:\\Study\\java\\filesudt\\send\\12.rmvb", "E:\\Study\\java\\filesudt\\rec\\1.rmvb"); + rec.start(); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e8/70971d3ce5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/70971d3ce5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..bac3d45 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/70971d3ce5ac001716b9ca6d5abb90bc @@ -0,0 +1,243 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + else + { + recData(); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b0ddd35cf7ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b0ddd35cf7ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c003c4c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b0ddd35cf7ab001710ff8a7c6bda0fb8 @@ -0,0 +1,129 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + for(int i=0;i list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取有数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + index=i; + i=-1;//重新遍历 + + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e9/4013f50ee5ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/4013f50ee5ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..9308681 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/4013f50ee5ac001716b9ca6d5abb90bc @@ -0,0 +1,236 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e9/90cd219a05ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/90cd219a05ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f1ea5ca --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/90cd219a05ac001710ff8a7c6bda0fb8 @@ -0,0 +1,92 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除session:"+); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e9/a022a50403ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/a022a50403ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f8b7f84 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/a022a50403ac001710ff8a7c6bda0fb8 @@ -0,0 +1,15 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; + +/** + * @author jinyu + * @param + * + */ +public class SocketQueue extends ReferenceQueue { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e9/d006eeec21ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/d006eeec21ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..582501f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/d006eeec21ac001710ff8a7c6bda0fb8 @@ -0,0 +1,211 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=1500; + private long sumLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public void pauseOutput() + { + try { + client.getOutputStream().pauseOutput(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + public byte[] read() + { + byte[] result=null; + if(client!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + byte[] buf=new byte[bufSize];//数据区 + int index=0; + int r=0; + try { + while(true) + { + r=client.read(readBytes); + if(r==-1) + { + break; + } + else + { + if(r<=bufSize) + { + //result=new byte[r]; + //System.arraycopy(readBytes, 0, result, 0, r); + if(index+r hash=new ConcurrentHashMap(); +// private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + // + if(!list.isEmpty()) + { + for(int i=0;ihandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + logger.info("DataPacket udt:"+p.getPacketSequenceNumber()); + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + logger.info("largestReceivedSeqNumber:"+largestReceivedSeqNumber); + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + logger.info("sendNAK:"+currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + logger.info("receiverLossList remove:"+currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + logger.info("sendNAK List:"+sequenceNumbers.size()); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/eb/2021a16626ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/eb/2021a16626ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..b981a90 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/eb/2021a16626ac001710ff8a7c6bda0fb8 @@ -0,0 +1,87 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference objsocket=(SocketReference) q.poll(); + if(objsocket.get()!=null) + { + judpSocket socket=objsocket.get(); + if(socket.getCloseState()) + { + + socket.close(); + } + } + + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/eb/b0e8f93623ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/eb/b0e8f93623ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ae150bf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/eb/b0e8f93623ac001710ff8a7c6bda0fb8 @@ -0,0 +1,232 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData= PackagetSub.split(data); + for(int i=0;i + *
    + *
  • set initial sequence number
  • + *
  • send response handshake
  • + *
+ * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ + ConnectionHandshake responseHandshake = new ConnectionHandshake(); + //compare the packet size and choose minimun + long clientBufferSize=handshake.getPacketSize(); + long myBufferSize=getDatagramSize(); + long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); + setDatagramSize((int)bufferSize); + responseHandshake.setPacketSize(bufferSize); + responseHandshake.setUdtVersion(4); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); + //tell peer what the socket ID on this side is + responseHandshake.setSocketID(mySocketID); + responseHandshake.setDestinationID(this.getDestination().getSocketID()); + responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); + endPoint.doSend(responseHandshake); + } + + + + +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ec/00a2d3dd6fa800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/ec/00a2d3dd6fa800171a8482560d609ceb new file mode 100644 index 0000000..cbbf754 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ec/00a2d3dd6fa800171a8482560d609ceb @@ -0,0 +1,82 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + i=-1;//重新遍历 + index=i; + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ec/803ad67e6da800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/ec/803ad67e6da800171a8482560d609ceb new file mode 100644 index 0000000..e15d011 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ec/803ad67e6da800171a8482560d609ceb @@ -0,0 +1,42 @@ +/** + * + */ +package net.File; + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFile { + private static Logger log=Logger.getLogger(TestSendFile.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + SendFiles send=new SendFiles("127.0.0.1", 5555); + FilesWatch watch=new FilesWatch(); + String dir="F:/monitor"; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ec/80b1fc5504ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/ec/80b1fc5504ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ba0d566 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ec/80b1fc5504ac001710ff8a7c6bda0fb8 @@ -0,0 +1,79 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + while((k = (SocketReference) q.remove()) != null) { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ec/b0b90ce869a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/ec/b0b90ce869a800171a8482560d609ceb new file mode 100644 index 0000000..46c353d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ec/b0b90ce869a800171a8482560d609ceb @@ -0,0 +1,113 @@ +/** + * + */ +package judp; + +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.SynchronousQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTServerSocket; +import udt.UDTSocket; + +/** + * @author jinyu + * 服务端接收封装 + * 服务端 + */ +public class judpServer { +private UDTServerSocket server=null; +private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=accept(); + } + judpSocket jsocket=new judpSocket(socket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ed/d0307bf0c4ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/d0307bf0c4ad0017181ed9113883eda9 new file mode 100644 index 0000000..9c938ec --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/d0307bf0c4ad0017181ed9113883eda9 @@ -0,0 +1,516 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ed/e076043e66a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/e076043e66a800171a8482560d609ceb new file mode 100644 index 0000000..51216ee --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/e076043e66a800171a8482560d609ceb @@ -0,0 +1,50 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + for( int i = 0 ; i < list.size() ; i++) { + try { + if(list.get(i).getInputStream().isHasData()) + { + return list.get(i); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ee/2060f2c92dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/ee/2060f2c92dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..1fa20a8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ee/2060f2c92dac001710ff8a7c6bda0fb8 @@ -0,0 +1,100 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/timespan/1000; + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ee/e063a0e405ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/ee/e063a0e405ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..c2ec32b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ee/e063a0e405ac001710ff8a7c6bda0fb8 @@ -0,0 +1,96 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + private long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f/007161e403ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f/007161e403ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..1e5437c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f/007161e403ac001710ff8a7c6bda0fb8 @@ -0,0 +1,70 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + WeakReference k; + while((k = (WeakReference) q.remove()) != null) { + System.out.println((cnt++) + "回收了:" + k); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f/80cfa981e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/f/80cfa981e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..222dbd1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f/80cfa981e4ac001716b9ca6d5abb90bc @@ -0,0 +1,220 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f0/b00e1d621dac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f0/b00e1d621dac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..41c29ef --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f0/b00e1d621dac001710ff8a7c6bda0fb8 @@ -0,0 +1,62 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int num=0; +private volatile int sum=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} +private boolean check() +{ + if(num>=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + int index=0; + for(int i=0;i100) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + int sum=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + sum+=bufSize; + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + sum+=count; + } + + } + client.close(); + dis.close(); + log.info("发送完成:"+f.getName()); + } + catch(Exception ex) + { + + } + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f1/4058227a03ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f1/4058227a03ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7db9771 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f1/4058227a03ac001710ff8a7c6bda0fb8 @@ -0,0 +1,76 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private LinkedBlockingQueue> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + startThread(); + startGC(); + this.endPoint=point; + + } + private void startGC() { + + + } + private void startThread() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + WeakReference objsocket=queue.take(); + if(objsocket.get()!=null) + { + judpSocket socket=objsocket.get(); + if(socket.getCloseState()) + { + socket.close(); + } + } + + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f1/a0ccf39ca2ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/f1/a0ccf39ca2ad0017181ed9113883eda9 new file mode 100644 index 0000000..4ba8bae --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f1/a0ccf39ca2ad0017181ed9113883eda9 @@ -0,0 +1,102 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * @author jinyu + * + */ +public class ReadXml { + public static String getPath() { + URL url = ReadXml.class.getProtectionDomain().getCodeSource().getLocation(); + String filePath = null; + try { + filePath = URLDecoder.decode(url.getPath(), "utf-8");// 转化为utf-8编码 + } catch (Exception e) { + e.printStackTrace(); + } + if (filePath.endsWith(".jar")) {// 可执行jar包运行的结果里包含".jar" + // 截取路径中的jar包名 + filePath = filePath.substring(0, filePath.lastIndexOf("/") + 1); + } + + File file = new File(filePath); + + // /If this abstract pathname is already absolute, then the pathname + // string is simply returned as if by the getPath method. If this + // abstract pathname is the empty abstract pathname then the pathname + // string of the current user directory, which is named by the system + // property user.dir, is returned. + filePath = file.getAbsolutePath();//得到windows下的正确路径 + return filePath; + } +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Document doc = null; + try { + doc = (Document) builder.parse(is); + } catch (SAXException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + NodeList list=doc.getElementsByTagName("IP"); + String ip= list.item(0).getTextContent(); + list=doc.getElementsByTagName("Port"); + String port=list.item(0).getTextContent(); + list=doc.getElementsByTagName("Dir"); + String dir=list.item(0).getTextContent(); + String strxml=ip+","+port+","+dir; + return strxml; + } +private String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f1/f0b1078018ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f1/f0b1078018ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f2/00fb9210c5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/00fb9210c5ad0017181ed9113883eda9 new file mode 100644 index 0000000..60d3290 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/00fb9210c5ad0017181ed9113883eda9 @@ -0,0 +1,516 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + // + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + for(long s=lastAckSequenceNumber;s move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f2/205b62d228ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/205b62d228ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..1f34d9c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/205b62d228ac001710ff8a7c6bda0fb8 @@ -0,0 +1,99 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=16; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i> queue=new LinkedBlockingQueue>(); + private final ReferenceQueue q = new ReferenceQueue(); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + private void startThread() { + + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + queue.add(socket); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f2/7032eb2669a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/7032eb2669a800171a8482560d609ceb new file mode 100644 index 0000000..d0ed24b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/7032eb2669a800171a8482560d609ceb @@ -0,0 +1,83 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f2/70e487be1fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/70e487be1fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..44126c5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/70e487be1fac001710ff8a7c6bda0fb8 @@ -0,0 +1,39 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); + private ConcurrentLinkedQueue queue=new ConcurrentLinkedQueue(); +public boolean addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + boolean r= struct.addData(data); + if(r) + { + byte[]result =struct.getData(); + byte[] tmp=new byte[result.length]; + System.arraycopy(result, 0, tmp, 0, tmp.length); + queue.offer(tmp); + struct.clear(); + } + return r; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f3/f0a22d5cb5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/f3/f0a22d5cb5ad0017181ed9113883eda9 new file mode 100644 index 0000000..3a6989e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f3/f0a22d5cb5ad0017181ed9113883eda9 @@ -0,0 +1,522 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;s0) + { + if(lastAckSequenceNumber/10000!=ackNumber/10000) + { + //修正 + //ackNumber 特别大,则会全部删除,特别小,一个都不会删除 + if(lastAckSequenceNumberthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + } + } + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f4/601a0f24e4ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/f4/601a0f24e4ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..81438ce --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f4/601a0f24e4ac001716b9ca6d5abb90bc @@ -0,0 +1,210 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + ConcurrentLinkedQueue recData=new ConcurrentLinkedQueue(); + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + private void recData(byte[] data) + { + + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(true) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + if(writeFile(tmp)) + { + ss.close(); + break; + } + // + + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f4/f0223ffad6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/f4/f0223ffad6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..0075291 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f4/f0223ffad6ac001716b9ca6d5abb90bc @@ -0,0 +1,274 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + System.out.println("sendBlocking start"); + client.sendBlocking(data); + r=data.length; + sumLen+=r; + System.out.println("sendBlocking end"); + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean Start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + //judpSocket jsocket=new judpSocket(csocket); + + //SocketManager.getInstance().addGC(jsocket,csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} + +/** + * 返回连接的socket + */ +public judpSocket accept() +{ +try { + judpSocket jsocket= sessionHandoff.take(); + return jsocket; +} catch (InterruptedException e) { + logger.info("judpSocket接收中断:"+e.getMessage()); + e.printStackTrace(); +} +return null; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f6/305344955ca800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/f6/305344955ca800171a8482560d609ceb new file mode 100644 index 0000000..a8661c2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f6/305344955ca800171a8482560d609ceb @@ -0,0 +1,229 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Destination; +import udt.packets.Shutdown; +import udt.util.UDTStatistics; + +public class UDTClient { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + private final UDPEndPoint clientEndpoint; + private ClientSession clientSession; + private boolean close=false; + private Thread closeThread=null;//cd + private final int waitClose=10*1000; + public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address,localport); + logger.info("Created client endpoint on port "+localport); + } + + public UDTClient(InetAddress address)throws SocketException, UnknownHostException{ + //create endpoint + clientEndpoint=new UDPEndPoint(address); + logger.info("Created client endpoint on port "+clientEndpoint.getLocalPort()); + } + + public UDTClient(UDPEndPoint endpoint)throws SocketException, UnknownHostException{ + clientEndpoint=endpoint; + } + + /** + * establishes a connection to the given server. + * Starts the sender thread. + * @param host + * @param port + * @throws UnknownHostException + */ + public void connect(String host, int port)throws InterruptedException, UnknownHostException, IOException{ + InetAddress address=InetAddress.getByName(host); + Destination destination=new Destination(address,port); + //create client session... + clientSession=new ClientSession(clientEndpoint,destination); + clientEndpoint.addSession(clientSession.getSocketID(), clientSession); + + clientEndpoint.start(); + clientSession.connect(); + //wait for handshake + while(!clientSession.isReady()){ + Thread.sleep(500); + } + logger.info("The UDTClient is connected"); + Thread.sleep(500); + } + + /** + * sends the given data asynchronously + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + public void send(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWrite(data); + } + + public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + clientSession.getSocket().doWriteBlocking(data); + } + + public int read(byte[]data)throws IOException, InterruptedException{ + return clientSession.getSocket().getInputStream().read(data); + } + + /** + * flush outstanding data (and make sure it is acknowledged) + * @throws IOException + * @throws InterruptedException + */ + public void flush()throws IOException, InterruptedException{ + clientSession.getSocket().flush(); + } + + + public void shutdown()throws IOException{ + + if (clientSession.isReady()&& clientSession.active==true) + { + Shutdown shutdown = new Shutdown(); + shutdown.setDestinationID(clientSession.getDestination().getSocketID()); + shutdown.setSession(clientSession); + try{ + clientEndpoint.doSend(shutdown); + TimeUnit.MILLISECONDS.sleep(100); + } + catch(Exception e) + { + logger.log(Level.SEVERE,"ERROR: Connection could not be stopped!",e); + } + clientSession.getSocket().getReceiver().stop(); + clientEndpoint.stop(); + //cd 添加 + clientEndpoint.removeSession(clientSession.getSocketID()); + clientSession.getSocket().getSender().stop(); + close=true; + } + } + + public UDTInputStream getInputStream()throws IOException{ + return clientSession.getSocket().getInputStream(); + } + + public UDTOutputStream getOutputStream()throws IOException{ + return clientSession.getSocket().getOutputStream(); + } + + public UDPEndPoint getEndpoint()throws IOException{ + return clientEndpoint; + } + + public UDTStatistics getStatistics(){ + return clientSession.getStatistics(); + } + + public long getSocketID() + { + //cd + return clientSession.getSocketID(); + } + + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if() + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } + + public boolean isClose() + { + return close; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f6/6074ea1c65a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/f6/6074ea1c65a800171a8482560d609ceb new file mode 100644 index 0000000..b07dda3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f6/6074ea1c65a800171a8482560d609ceb @@ -0,0 +1,61 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + + + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f6/70c6c0fe05ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f6/70c6c0fe05ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..842ced2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f6/70c6c0fe05ac001710ff8a7c6bda0fb8 @@ -0,0 +1,95 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; + +import java.util.WeakHashMap; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + private long num=0; + /** + * 测试使用 + */ + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + if(num%200==0) + { + System.gc(); + } + num++; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f6/80457721b5ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/f6/80457721b5ad0017181ed9113883eda9 new file mode 100644 index 0000000..1bcb149 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f6/80457721b5ad0017181ed9113883eda9 @@ -0,0 +1,515 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + // + } + + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f7/40b0cfa5d6ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/40b0cfa5d6ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..350dea8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/40b0cfa5d6ac001716b9ca6d5abb90bc @@ -0,0 +1,288 @@ +package udt.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取;也要外部快速读取 + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } + notEmpty.signal(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * unit + * @param unit a TimeUnit determining how to interpret the + * timeout parameter + * @return data chunk, or null if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + if(this.islagerRead) + { + // cd + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + + if(readPosition==size) + {readPosition=0; + if(this.islagerRead) + { + //cd + clearDeHash(this.size-leftNum); + } + } + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } + + /** + * 设置大数据读取 + * @param islarge + */ + public void setLargeRead(boolean islarge) + { + this.islagerRead=islarge; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f7/603bf12c1fac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/603bf12c1fac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..931c38e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/603bf12c1fac001710ff8a7c6bda0fb8 @@ -0,0 +1,28 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public DataStruct addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + boolean r= struct.addData(data); + return struct; +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f7/702d21411aac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/702d21411aac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f8c9a59 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/702d21411aac001710ff8a7c6bda0fb8 @@ -0,0 +1,76 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + public static byte[][] split(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int num=data.length/bufsize+data.length%bufsize; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + byte[][] result=new byte[num][]; + for(int i=0;i list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public UDTSocket getSocket() +{ + UDTSocket find=null; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关闭 + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + +} +public void clear() +{ + list.clear(); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f8/60ddb5c326ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/f8/60ddb5c326ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..0152aaf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f8/60ddb5c326ac001710ff8a7c6bda0fb8 @@ -0,0 +1,234 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import udt.UDTClient; + +/** + * @author jinyu + * 客户端发送 + */ +public class judpClient { + private UDTClient client=null; + private final int bufSize=65535; + private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int len=0; + public judpClient(String lcoalIP,int port) + { + InetAddress addr = null; + try { + addr = InetAddress.getByName(lcoalIP); + } catch (UnknownHostException e1) { + + e1.printStackTrace(); + } + + try { + client=new UDTClient(addr,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient() + { + try { + client=new UDTClient(null,0); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public judpClient(int port) + { + try { + client=new UDTClient(null,port); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + SocketManager.getInstance().addGC(this,client); + } + public boolean connect(String ip,int port) + { + boolean isSucess=false; + if(client!=null) + { + try { + client.connect(ip, port); + isSucess=true; + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + return isSucess; + } + public int sendData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + if(client!=null) + { + try { + client.sendBlocking(data); + r=data.length; + sumLen+=r; + } catch (IOException e) { + + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return r; + } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData= PackagetSub.splitData(data); + for(int i=0;i=buffer.length) + { + //检查成功 + if(sum==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i sessionHandoff=new SynchronousQueue(); +private boolean isStart=true; +private boolean isSucess=true; +private boolean isRWMaster=true;//与默认值一致 +private boolean islagerRead; +private static final Logger logger=Logger.getLogger(judpServer.class.getName()); + +/** + * 关闭服务端 + */ +public void close() +{ + isStart=false; + server.getEndpoint().stop(); +} + +/** + * + * @param port 端口 + */ +public judpServer(int port) +{ + + try { + server=new UDTServerSocket(port); + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ +public judpServer(String localIP,int port) +{ + try { + InetAddress addr= InetAddress.getByName(localIP); + server=new UDTServerSocket(addr,port); + + } catch (SocketException e) { + logger.log(Level.WARNING, "绑定失败:"+e.getMessage()); + isSucess=false; + } catch (UnknownHostException e) { + isSucess=false; + e.printStackTrace(); + } +} + +/** + * 启动接收 + */ +public boolean start() +{ + if(!isStart||!isSucess) + { + logger.log(Level.WARNING, "已经关闭的监听或监听端口不能使用"); + return false; + } + Thread serverThread=new Thread(new Runnable() { + + @Override + public void run() { + while(isStart) + { + try { + UDTSocket csocket= server.accept(); + SocketControls.getInstance().addSocket(csocket); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + }); + serverThread.setDaemon(true); + serverThread.setName("judpServer_"+System.currentTimeMillis()); + serverThread.start(); + return true; +} +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ +public void resetBufMaster(boolean isRead) +{ + this.isRWMaster=isRead; + +} + +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.islagerRead=islarge; +} +/** + * 返回连接的socket + */ +public judpSocket accept() +{ + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fa/1096727405ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/fa/1096727405ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7d221cc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fa/1096727405ac001710ff8a7c6bda0fb8 @@ -0,0 +1,87 @@ +/** + * + */ +package judp; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import udt.UDPEndPoint; +import udt.UDTClient; +import udt.UDTSession; + +/** + * @author jinyu + * 管理接受端的judpSocket + */ +public class judpSocketManager { + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private final ReferenceQueue q = new ReferenceQueue(); + private final WeakHashMap hashMap=new WeakHashMap (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fb/30fc8d1b66a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/fb/30fc8d1b66a800171a8482560d609ceb new file mode 100644 index 0000000..6575b72 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fb/30fc8d1b66a800171a8482560d609ceb @@ -0,0 +1,45 @@ +/** + * + */ +package judp; + +import java.util.ArrayList; + +import udt.UDTSocket; + +/** + * @author jinyu + * 按照目的分组 + */ +public class judpGroupSocket { +private ArrayList list=new ArrayList(); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取数据socket + * @return + */ +public judpGroupSocket getSocket() +{ + for( int i = 0 ; i < list.size() ; i++) { + if(list.get(i).getInputStream().isHasData()) + { + return list.get(i); + } + } + return null; + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fb/e0a01d43f2ab001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/fb/e0a01d43f2ab001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..549b0fd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fb/e0a01d43f2ab001710ff8a7c6bda0fb8 @@ -0,0 +1,115 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); +// private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + int num=0; + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + num++; + // + if(!list.isEmpty()) + { + for(int i=0;ihandoffQueue; + + private Thread receiverThread; + + private volatile boolean stopped=false; + + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + + /** + * if set to true connections will not expire, but will only be + * closed by a Shutdown message + */ + public static boolean connectionExpiryDisabled=false; + + private final boolean storeStatistics; + + + + /** + * create a receiver with a valid {@link UDTSession} + * @param session + */ + public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ + this.endpoint = endpoint; + this.session=session; + this.sessionUpSince=System.currentTimeMillis(); + this.statistics=session.getStatistics(); + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + ackHistoryWindow = new AckHistoryWindow(16); + packetHistoryWindow = new PacketHistoryWindow(16); + receiverLossList = new ReceiverLossList(); + packetPairWindow = new PacketPairWindow(16); + largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; + bufferSize=session.getReceiveBufferSize(); + handoffQueue=new ArrayBlockingQueue(4*session.getFlowWindowSize()); + storeStatistics=Boolean.getBoolean("udt.receiver.storeStatistics"); + initMetrics(); + start(); + } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + if(!storeStatistics)return; + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + + + //starts the sender algorithm + private void start(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); + while(!stopped){ + receiverAlgorithm(); + } + } + catch(Exception ex){ + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING RECEIVER for "+session); + } + }; + receiverThread=UDTThreadFactory.get().newThread(r); + receiverThread.start(); + } + + /* + * packets are written by the endpoint + */ + protected void receive(UDTPacket p)throws IOException{ + if(storeStatistics)dgReceiveInterval.end(); + handoffQueue.offer(p); + if(storeStatistics)dgReceiveInterval.begin(); + } + + /** + * receiver algorithm + * see specification P11. + */ + public void receiverAlgorithm()throws InterruptedException,IOException{ + //check ACK timer + long currentTime=Util.getCurrentTime(); + if(nextACKseqNumbers=receiverLossList.getFilteredSequenceNumbers(roundTripTime,true); + sendNAK(seqNumbers); + } + + /** + * process EXP event (see spec. p 13) + */ + protected void processEXPEvent()throws IOException{ + if(session.getSocket()==null)return; + UDTSender sender=session.getSocket().getSender(); + //put all the unacknowledged packets in the senders loss list + sender.putUnacknowledgedPacketsIntoLossList(); + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ + if(!connectionExpiryDisabled &&!stopped){ + sendShutdown(); + stop(); + logger.info("Session "+session+" expired."); + return; + } + } + if(!sender.haveLostPackets()){ + sendKeepAlive(); + } + expCount++; + } + + protected void processUDTPacket(UDTPacket p)throws IOException{ + //(3).Check the packet type and process it according to this. + + if(!p.isControlPacket()){ + DataPacket dp=(DataPacket)p; + if(storeStatistics){ + dataPacketInterval.end(); + dataProcessTime.begin(); + } + onDataPacketReceived(dp); + if(storeStatistics){ + dataProcessTime.end(); + dataPacketInterval.begin(); + } + } + + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ + Acknowledgment2 ack2=(Acknowledgment2)p; + onAck2PacketReceived(ack2); + } + + else if (p instanceof Shutdown){ + onShutdown(); + } + + } + + //every nth packet will be discarded... for testing only of course + public static int dropRate=0; + + //number of received data packets + private int n=0; + + protected void onDataPacketReceived(DataPacket dp)throws IOException{ + long currentSequenceNumber = dp.getPacketSequenceNumber(); + + //for TESTING : check whether to drop this packet +// n++; +// //if(dropRate>0 && n % dropRate == 0){ +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } + + long currentDataPacketArrivalTime = Util.getCurrentTime(); + + /*(4).if the seqNo of the current data packet is 16n+1,record the + time interval between this packet and the last data packet + in the packet pair window*/ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ + long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; + packetPairWindow.add(interval); + } + + //(5).record the packet arrival time in the PKT History Window. + packetHistoryWindow.add(currentDataPacketArrivalTime); + + + //store current time + lastDataPacketArrivalTime=currentDataPacketArrivalTime; + + + //(6).number of detected lossed packet + /*(6.a).if the number of the current data packet is greater than LSRN+1, + put all the sequence numbers between (but excluding) these two values + into the receiver's loss list and send them to the sender in an NAK packet*/ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ + sendNAK(currentSequenceNumber); + } + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ + /*(6.b).if the sequence number is less than LRSN,remove it from + * the receiver's loss list + */ + receiverLossList.remove(currentSequenceNumber); + } + + statistics.incNumberOfReceivedDataPackets(); + + //(7).Update the LRSN + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ + largestReceivedSeqNumber=currentSequenceNumber; + } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } + } + + /** + * write a NAK triggered by a received sequence number that is larger than + * the largestReceivedSeqNumber + 1 + * @param currentSequenceNumber - the currently received sequence number + * @throws IOException + */ + protected void sendNAK(long currentSequenceNumber)throws IOException{ + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(largestReceivedSeqNumber+1, currentSequenceNumber); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + //put all the sequence numbers between (but excluding) these two values into the + //receiver loss list + for(long i=largestReceivedSeqNumber+1;isequenceNumbers)throws IOException{ + if(sequenceNumbers.size()==0)return; + NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); + nAckPacket.setSession(session); + nAckPacket.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(nAckPacket); + statistics.incNumberOfNAKSent(); + } + + protected long sendLightAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt=buildLightAcknowledgement(ackNumber); + endpoint.doSend(acknowledgmentPkt); + statistics.incNumberOfACKSent(); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + protected long sendAcknowledgment(long ackNumber)throws IOException{ + Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); + //set the estimate link capacity + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); + acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); + //set the packet arrival rate + packetArrivalSpeed=packetHistoryWindow.getPacketArrivalSpeed(); + acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); + + endpoint.doSend(acknowledgmentPkt); + + statistics.incNumberOfACKSent(); + statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); + return acknowledgmentPkt.getAckSequenceNumber(); + } + + //builds a "light" Acknowledgement + private Acknowledgement buildLightAcknowledgement(long ackNumber){ + Acknowledgement acknowledgmentPkt = new Acknowledgement(); + //the packet sequence number to which all the packets have been received + acknowledgmentPkt.setAckNumber(ackNumber); + //assign this ack a unique increasing ACK sequence number + acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); + acknowledgmentPkt.setRoundTripTime(roundTripTime); + acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); + //set the buffer size + acknowledgmentPkt.setBufferSize(bufferSize); + + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); + acknowledgmentPkt.setSession(session); + + return acknowledgmentPkt; + } + + /** + * spec p. 13:
+ 1) Locate the related ACK in the ACK History Window according to the + ACK sequence number in this ACK2.
+ 2) Update the largest ACK number ever been acknowledged.
+ 3) Calculate new rtt according to the ACK2 arrival time and the ACK + departure time, and update the RTT value as: RTT = (RTT * 7 + + rtt) / 8.
+ 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4.
+ 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN.
+ */ + protected void onAck2PacketReceived(Acknowledgment2 ack2){ + AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); + if(entry!=null){ + long ackNumber=entry.getAckNumber(); + largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + + long rtt=entry.getAge(); + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; + roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; + statistics.setRTT(roundTripTime, roundTripTimeVar); + } + } + + protected void sendKeepAlive()throws IOException{ + KeepAlive ka=new KeepAlive(); + ka.setDestinationID(session.getDestination().getSocketID()); + ka.setSession(session); + endpoint.doSend(ka); + } + + protected void sendShutdown()throws IOException{ + Shutdown s=new Shutdown(); + s.setDestinationID(session.getDestination().getSocketID()); + s.setSession(session); + endpoint.doSend(s); + } + + private volatile long ackSequenceNumber=0; + + protected void resetEXPTimer(){ + nextEXP=Util.getCurrentTime()+expTimerInterval; + expCount=0; + } + + protected void resetEXPCount(){ + expCount=0; + } + + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + + protected void onShutdown()throws IOException{ + stop(); + } + + public void stop()throws IOException{ + stopped=true; + session.getSocket().close(); + //stop our sender as well + session.getSocket().getSender().stop(); + } + + @Override + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("UDTReceiver ").append(session).append("\n"); + sb.append("LossList: "+receiverLossList); + return sb.toString(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fc/10f958adb3ad0017181ed9113883eda9 b/.metadata/.plugins/org.eclipse.core.resources/.history/fc/10f958adb3ad0017181ed9113883eda9 new file mode 100644 index 0000000..969d09f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fc/10f958adb3ad0017181ed9113883eda9 @@ -0,0 +1,514 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.DataPacket; +import udt.packets.KeepAlive; +import udt.packets.NegativeAcknowledgement; +import udt.sender.SenderLossList; +import udt.util.MeanThroughput; +import udt.util.MeanValue; +import udt.util.SequenceNumber; +import udt.util.UDTStatistics; +import udt.util.UDTThreadFactory; +import udt.util.Util; + + +/** + * sender part of a UDT entity + * + * @see UDTReceiver + */ +public class UDTSender { + + private static final Logger logger=Logger.getLogger(UDTClient.class.getName()); + + private final UDPEndPoint endpoint; + + private final UDTSession session; + + private final UDTStatistics statistics; + + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets + private final SenderLossList senderLossList; + + //sendBuffer stores the sent data packets and their sequence numbers + private final MapsendBuffer; + + //sendQueue contains the packets to send + private final BlockingQueuesendQueue; + + //thread reading packets from send queue and sending them + private Thread senderThread; + + //protects against races when reading/writing to the sendBuffer + private final Object sendLock=new Object(); + + //number of unacknowledged data packets + private final AtomicInteger unacknowledged=new AtomicInteger(0); + + //for generating data packet sequence numbers + private volatile long currentSequenceNumber=0; + + //the largest data packet sequence number that has actually been sent out + private volatile long largestSentSequenceNumber=-1; + + //last acknowledge number, initialised to the initial sequence number + private volatile long lastAckSequenceNumber; + + private volatile boolean started=false; + + private volatile boolean stopped=false; + + private volatile boolean paused=false; + + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK + private final AtomicReference waitForAckLatch=new AtomicReference(); + + //used by the sender to wait for an ACK of a certain sequence number + private final AtomicReference waitForSeqAckLatch=new AtomicReference(); + + private final boolean storeStatistics; + + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + this.endpoint= endpoint; + this.session=session; + statistics=session.getStatistics(); + senderLossList=new SenderLossList(); + sendBuffer=new ConcurrentHashMap(session.getFlowWindowSize(),0.75f,2); + sendQueue = new ArrayBlockingQueue(1000); + lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); + storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); + initMetrics(); + doStart(); + } + + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private MeanThroughput throughput; + private void initMetrics(){ + if(!storeStatistics)return; + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + statistics.addMetric(throughput); + } + + /** + * start the sender thread + */ + public void start(){ + logger.info("Starting sender for "+session); + startLatch.countDown(); + started=true; + } + + //starts the sender algorithm + private void doStart(){ + Runnable r=new Runnable(){ + @Override + public void run(){ + try{ + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + catch(IOException ex){ + ex.printStackTrace(); + logger.log(Level.SEVERE,"",ex); + } + logger.info("STOPPING SENDER for "+session); + } + }; + senderThread=UDTThreadFactory.get().newThread(r); + senderThread.start(); + } + + + /** + * sends the given data packet, storing the relevant information + * + * @param data + * @throws IOException + * @throws InterruptedException + */ + private void send(DataPacket p)throws IOException{ + synchronized(sendLock){ + if(storeStatistics){ + dgSendInterval.end(); + dgSendTime.begin(); + } + endpoint.doSend(p); + if(storeStatistics){ + dgSendTime.end(); + dgSendInterval.begin(); + throughput.end(); + throughput.begin(); + } + sendBuffer.put(p.getPacketSequenceNumber(), p); + unacknowledged.incrementAndGet(); + } + statistics.incNumberOfSentDataPackets(); + } + + /** + * writes a data packet into the sendQueue, waiting at most for the specified time + * if this is not possible due to a full send queue + * + * @return trueif the packet was added, false if the + * packet could not be added because the queue was full + * @param p + * @param timeout + * @param units + * @return + * @throws IOException + * @throws InterruptedException + */ + protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + if(!started)start(); + return sendQueue.offer(p,timeout,units); + } + + //receive a packet from server from the peer + protected void receive(UDTPacket p)throws IOException{ + if (p instanceof Acknowledgement) { + Acknowledgement acknowledgement=(Acknowledgement)p; + onAcknowledge(acknowledgement); + } + else if (p instanceof NegativeAcknowledgement) { + NegativeAcknowledgement nak=(NegativeAcknowledgement)p; + onNAKPacketReceived(nak); + } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } + } + + protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + + CongestionControl cc=session.getCongestionControl(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ + long rttVar=acknowledgement.getRoundTripTimeVar(); + cc.setRTT(rtt,rttVar); + statistics.setRTT(rtt, rttVar); + } + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); + //need to remove all sequence numbers up the ack number from the sendBuffer + boolean removed=false; + boolean one=false; + for(long s=lastAckSequenceNumber;sthis.currentSequenceNumber) + { + //比当前发送包都大,修正 cd + lastAckSequenceNumber=ackNumber; + } + } + + } + + //send ACK2 packet to the receiver + sendAck2(ackNumber); + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + } + + /** + * procedure when a NAK is received (spec. p 14) + * @param nak + */ + protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + for(Integer i: nak.getDecodedLossInfo()){ + senderLossList.insert(Long.valueOf(i)); + } + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); + session.getSocket().getReceiver().resetEXPTimer(); + statistics.incNumberOfNAKReceived(); + + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + } + return; + } + + //send single keep alive packet -> move to socket! + protected void sendKeepAlive()throws Exception{ + KeepAlive keepAlive = new KeepAlive(); + //TODO + keepAlive.setSession(session); + endpoint.doSend(keepAlive); + } + + protected void sendAck2(long ackSequenceNumber)throws IOException{ + Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); + ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); + ackOfAckPkt.setSession(session); + ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); + endpoint.doSend(ackOfAckPkt); + } + + /** + * sender algorithm + */ + long iterationStart; + public void senderAlgorithm()throws InterruptedException, IOException{ + while(!paused){ + iterationStart=Util.getCurrentTime(); + + //if the sender's loss list is not empty + if (!senderLossList.isEmpty()) { + Long entry=senderLossList.getFirstEntry(); + handleResubmit(entry); + logger.info("senderLossList:"+entry); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); + } + } + + //wait + if(largestSentSequenceNumber % 16 !=0){ + long snd=(long)session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + if(stopped)return; + } + } + } + } + + /** + * re-submits an entry from the sender loss list + * @param entry + */ + protected void handleResubmit(Long seqNumber){ + try { + //retransmit the packet and remove it from the list + DataPacket pktToRetransmit = sendBuffer.get(seqNumber); + if(pktToRetransmit!=null){ + endpoint.doSend(pktToRetransmit); + statistics.incNumberOfRetransmittedDataPackets(); + } + }catch (Exception e) { + logger.log(Level.WARNING,"",e); + } + } + + /** + * for processing EXP event (see spec. p 13) + */ + protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { + for(Long l: sendBuffer.keySet()){ + senderLossList.insert(l); + } + } + } + + /** + * the next sequence number for data packets. + * The initial sequence number is "0" + */ + public long getNextSequenceNumber(){ + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); + return currentSequenceNumber; + } + + public long getCurrentSequenceNumber(){ + return currentSequenceNumber; + } + + /** + * returns the largest sequence number sent so far + */ + public long getLargestSentSequenceNumber(){ + return largestSentSequenceNumber; + } + /** + * returns the last Ack. sequence number + */ + public long getLastAckSequenceNumber(){ + return lastAckSequenceNumber; + } + + boolean haveAcknowledgementFor(long sequenceNumber){ + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; + } + + boolean isSentOut(long sequenceNumber){ + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; + } + + boolean haveLostPackets(){ + return !senderLossList.isEmpty(); + } + + /** + * wait until the given sequence number has been acknowledged + * + * @throws InterruptedException + */ + public void waitForAck(long sequenceNumber)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + } + } + + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + } + + + public void stop(){ + stopped=true; + } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fc/a0fc077523ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/fc/a0fc077523ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..ca42c64 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fc/a0fc077523ac001710ff8a7c6bda0fb8 @@ -0,0 +1,305 @@ +/** + * + */ +package judp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import udt.UDTSession; +import udt.UDTSocket; +import udt.packets.Destination; + +/** + * @author jinyu + * + *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 + */ +public class judpSocket { +private final int bufSize=65535; +private UDTSocket socket=null; +private boolean isClose=false; +private long sendLen=0;//发送数据 +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +private int readLen=0; +public boolean getCloseState() +{ + return isClose; +} +public judpSocket(UDTSocket usocket) +{ + this.socket=usocket; + socketID=socket.getSession().getSocketID(); +} + +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + +/** + * 关闭 + * 等待数据完成关闭 + */ +public void close() +{ + isClose=true; + //不能真实关闭 + if(sendLen==0) + { + stop(); + System.out.println("物理关闭socket"); + } + else + { + //有过发送数据则缓冲 + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("物理关闭socket"); +} + +/** + * 读取数据 + * 返回接收的字节大小 + */ +public int readData(byte[]data) +{ + if(isClose) + { + return -1; + } + try { + int r=socket.getInputStream().read(data); + readLen+=r; + return r; + } catch (IOException e) { + e.printStackTrace(); + } + return -1; +} + +/** + * 读取全部数据 + */ +public byte[] readData() +{ + byte[] result=null; + if(socket!=null) + { + byte[] readBytes=new byte[bufSize];//接收区 + int r=0; + try { + while(true) + { + if(isClose) + { + return null; + } + r=socket.getInputStream().read(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + // + byte[] buf=new byte[r]; + System.arraycopy(readBytes, 0, buf, 0, r); + if(pack.addData(buf)) + { + result=pack.getData(); + break; + } + + + } + } + + } catch (IOException e) { + + e.printStackTrace(); + } + + } + + return result; +} + +/* + * 获取初始化序列 + */ +public long getInitSeqNo() +{ + if(socket!=null) + { + return socket.getSession().getInitialSequenceNumber(); + } + return 0; +} + +/** + * 发送包长 + */ +public int getDataStreamLen() +{ + return socket.getSession().getDatagramSize(); +} + +/** + * 目的socket + * @return + */ +public Destination getDestination() +{ + + if(socket!=null) + { + return socket.getSession().getDestination(); + } + Destination tmp = null; + try { + tmp = new Destination(InetAddress.getLocalHost(), 0); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return tmp; +} +/** + * 发送数据 + * 空数据不能发送 + */ +public boolean sendData(byte[]data) { + if(isClose) + { + return false; + } + try { + socket.getOutputStream().write(data); + sendLen=+1; + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; +} + +/** + * 获取远端host + * @return + */ +public String getRemoteHost() { +return socket.getSession().getDestination().getAddress().getHostName(); + +} + +/** + * 获取远端端口 + * @return + */ +public int getRemotePort() { + return socket.getSession().getDestination().getPort(); +} + +/** + * socketid + * @return + */ +public long getID() { + + return socketID; +} + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fd/a0c92a2bd7ac001716b9ca6d5abb90bc b/.metadata/.plugins/org.eclipse.core.resources/.history/fd/a0c92a2bd7ac001716b9ca6d5abb90bc new file mode 100644 index 0000000..35e51b5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fd/a0c92a2bd7ac001716b9ca6d5abb90bc @@ -0,0 +1,291 @@ +/********************************************************************************* + * Copyright (c) 2010 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package udt; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import udt.util.ReceiveBuffer; + +/** + * The UDTInputStream receives data blocks from the {@link UDTSocket} + * as they become available, and places them into an ordered, + * bounded queue (the flow window) for reading by the application + * + * + */ +public class UDTInputStream extends InputStream { + + //the socket owning this inputstream + private final UDTSocket socket; + + private final ReceiveBuffer receiveBuffer; + + //set to 'false' by the receiver when it gets a shutdown signal from the peer + //see the noMoreData() method + private final AtomicBoolean expectMoreData=new AtomicBoolean(true); + + private volatile boolean closed=false; + + private volatile boolean blocking=true; + + private volatile boolean hasData=false;//cd + + + + /** + * create a new {@link UDTInputStream} connected to the given socket + * @param socket - the {@link UDTSocket} + * @throws IOException + */ + public UDTInputStream(UDTSocket socket)throws IOException{ + this.socket=socket; + int capacity=socket!=null? 2 * socket.getSession().getFlowWindowSize() : 128 ; + long initialSequenceNum=socket!=null?socket.getSession().getInitialSequenceNumber():1; + receiveBuffer=new ReceiveBuffer(capacity,initialSequenceNum); + } + + private final byte[]single=new byte[1]; + + @Override + public int read()throws IOException{ + int b=0; + while(b==0) + b=read(single); + + if(b>0){ + return single[0]; + } + else { + return b; + } + } + + private AppData currentChunk=null; + //offset into currentChunk + int offset=0; + long id=-1; + @Override + public int read(byte[]target)throws IOException{ + try{ + int read=0; + updateCurrentChunk(false); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(blocking && read==0); + } + + if(read>0)return read; + if(closed)return -1; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; + //no more data + return -1; + + }catch(Exception ex){ + IOException e= new IOException(); + e.initCause(ex); + throw e; + } + } + + /** + * Reads the next valid chunk of application data from the queue
+ * + * In blocking mode,this method will block until data is available or the socket is closed, + * otherwise it will wait for at most 10 milliseconds. + * + * @throws InterruptedException + */ + private void updateCurrentChunk(boolean block)throws IOException{ + if(currentChunk!=null)return; + + while(true){ + try{ + if(block){ + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); + while (!closed && currentChunk==null){ + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); + } + } + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); + + }catch(InterruptedException ie){ + IOException ex=new IOException(); + ex.initCause(ie); + throw ex; + } + return; + } + } + + /** + * new application data + * @param data + * + */ + protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + hasData=true; + return receiveBuffer.offer(new AppData(sequenceNumber,data)); + } + + @Override + public void close()throws IOException{ + if(closed)return; + closed=true; + noMoreData(); + } + + public UDTSocket getSocket(){ + return socket; + } + + /** + * sets the blocking mode + * @param block + */ + public void setBlocking(boolean block){ + this.blocking=block; + } + + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + + /** + * notify the input stream that there is no more data + * @throws IOException + */ + protected void noMoreData()throws IOException{ + expectMoreData.set(false); + } + + /** + * 判断有没有数据进来 + * cd + * @return + */ + public boolean isHasData() + { + return hasData; + } + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + receiveBuffer.setBufMaster(isRead); + + } + + /** + * 设置大数据读取 + * 默认 false + * @param islarge + */ + public void setLargeRead(boolean islarge) + { + client.setLargeRead(islarge); + } + /** + * used for storing application data and the associated + * sequence number in the queue in ascending order + */ + public static class AppData implements Comparable{ + final long sequenceNumber; + final byte[] data; + public AppData(long sequenceNumber, byte[]data){ + this.sequenceNumber=sequenceNumber; + this.data=data; + } + + @Override + public int compareTo(AppData o) { + return (int)(sequenceNumber-o.sequenceNumber); + } + + @Override + public String toString(){ + return sequenceNumber+"["+data.length+"]"; + } + + public long getSequenceNumber(){ + return sequenceNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fe/502a91841bac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/fe/502a91841bac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..f433ecc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fe/502a91841bac001710ff8a7c6bda0fb8 @@ -0,0 +1,22 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author jinyu + * + */ +public class PackagetCombin { + private static ConcurrentHashMap hash=new ConcurrentHashMap(); +public static void addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int index=buf.getInt(); + int dataLen=buf.getInt(); + +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fe/e0de531569a800171a8482560d609ceb b/.metadata/.plugins/org.eclipse.core.resources/.history/fe/e0de531569a800171a8482560d609ceb new file mode 100644 index 0000000..972bd88 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fe/e0de531569a800171a8482560d609ceb @@ -0,0 +1,82 @@ +/** + * + */ +package judp; + + +import udt.UDTSocket; + +import java.util.ArrayList; +import java.util.Map.Entry; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * @author jinyu + * 接收端判断 + */ +public class SocketControls { + private static SocketControls instance; +private ConcurrentHashMap hash=new ConcurrentHashMap(); + private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + } + } + + }); + processSocket.setDaemon(true); + processSocket.setName("processSocket"); + processSocket.start(); + +} + +public static synchronized SocketControls getInstance() { + + if (instance == null) { + + instance = new SocketControls(); + + +} + return instance; +} +public void addSocket(UDTSocket socket) +{ + long id=socket.getSession().getDestination().getSocketID();//同一个目的 + judpGroupSocket group=hash.get(id); + if(group==null) + { + group=new judpGroupSocket(); + hash.put(id, group); + } + group.addSocket(socket); +} +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ff/7095ccf204ac001710ff8a7c6bda0fb8 b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/7095ccf204ac001710ff8a7c6bda0fb8 new file mode 100644 index 0000000..7377664 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/7095ccf204ac001710ff8a7c6bda0fb8 @@ -0,0 +1,32 @@ +/** + * + */ +package judp; + + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * @author jinyu + * @param + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + public SocketReference(T referent, long socketID2, ReferenceQueue q) { + super(referent,q); + } + public long getid() + { + return socketid; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.indexes/properties.index new file mode 100644 index 0000000000000000000000000000000000000000..1e099f3bff508a47e7cce4c8ace123e0c07a5306 GIT binary patch literal 80 zcmZQ%U|?VbVI~IA{GxQd)a0DZg5p%YlGMapz2y9&R0gi1)Pnrt%#!?~N(Mz_C8_C| TC153b?wKV4Mfqi!DXB#OWmFkc literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.markers.snap b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.markers.snap new file mode 100644 index 0000000000000000000000000000000000000000..1253ec8ad8c6db053a75de6169f668d2efcd4ee5 GIT binary patch literal 48 bcmZ?R*xjhShe1S2b=vdAllRFv5a0s<=in4O literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.syncinfo.snap b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.syncinfo.snap new file mode 100644 index 0000000000000000000000000000000000000000..1253ec8ad8c6db053a75de6169f668d2efcd4ee5 GIT binary patch literal 48 bcmZ?R*xjhShe1S2b=vdAllRFv5a0s<=in4O literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/org.eclipse.egit.core/GitProjectData.properties b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/org.eclipse.egit.core/GitProjectData.properties new file mode 100644 index 0000000..ffbf0b8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/org.eclipse.egit.core/GitProjectData.properties @@ -0,0 +1,3 @@ +#GitProjectData +#Tue Oct 10 22:54:18 CST 2017 +.gitdir=../.git diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/judt/.indexes/e4/9d/9c/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/judt/.indexes/e4/9d/9c/history.index new file mode 100644 index 0000000000000000000000000000000000000000..b85425175ec2f4de3ccd7609ef4b6574281f9169 GIT binary patch literal 65 zcmZQ#U|?WmP|zYsWMBXQiZ2#F literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/judt/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/judt/.indexes/properties.index new file mode 100644 index 0000000000000000000000000000000000000000..1e099f3bff508a47e7cce4c8ace123e0c07a5306 GIT binary patch literal 80 zcmZQ%U|?VbVI~IA{GxQd)a0DZg5p%YlGMapz2y9&R0gi1)Pnrt%#!?~N(Mz_C8_C| TC153b?wKV4Mfqi!DXB#OWmFkc literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/judt/.markers b/.metadata/.plugins/org.eclipse.core.resources/.projects/judt/.markers index faf387edcf3cb28d36d9d9616a2b626d6f4c3ae4..a576ee1a146f94042cb4591de5e1c393288b0594 100644 GIT binary patch delta 969 zcmZwGJxo(k7zW^TPbuMCX=%%COQJw(e}v1=rT!G<$AwUX2_{qr9n>^!qmpWjt<*sW zW1L(t-{7EwEQSr)bkZ2(VuFbdGBN1jB8he(A%u9(drzC(M#h)tyyrV#+gD?shT0fo z9;)#X&SFo~Q}mhFyjR;dX4mM9CoVMmzw+-et$UMPwwX+qg=9brF`+?&GP7CekpI?)R<@hMWPS4iD^tUuZn)CiBd2feH4uJY7Uuc zAx9kY5#*4#u^k6?VOFw0`jWrkt=A7K2yl$jNcmDXt`V9<&l=4^!W2U4`9 zFQH&ZT{3E?FI4&st1fCeI9hDCs8mHa%vm)6w==zr*@aFcbl9|$dJdbVTG}mSmAc} zCDE@wxIKCwHmG12oK1q7bD-ut=vN~lat_U!HXYz>3fFW+mgNSs88zrM4)@%{;ht6c a8!3uSbudF$qQjh>#=-UIZTVZxKKloW`}J4= literal 6182 zcmcJT+iw(A9LLYj^s-%{v}$cJ0;d7m5@9Mt6Gbkm-J&$5G;QHQf^~N0w4HW#W}P`x zt(VyFATcrN14UXR8ea_Y1tZ2tjFK1=;~!vnFg$3m(pRH^py=<+rQKb|vnSS>q`TXh z+1bzccYe3?LkP)eQ|E-I(@xjXI){l%{g*+a9WYFyOsG>TLMR1)aL7#(T5mgJ3eilX z;KF5{Dw^#Og{tl(N~5%EdyYm9>N1jhv%{!P8&{nnsybAHZ?~g0o=cn_-JojDB=FE$ zcD={a+0_F`GIR-})YqssPh3|WBfvI%IC~g(dDPx9Ml9l}l;~JfsWy&trmewm797KN z3_1;u0L+YOSft;}=ZM2jY=v{rZJED*6X6(B3!f;I?&rta`SrKUL0$C%wau3cJKI{DV(?CiBmAH(OXpMSLY_Qk~urrmH{O*E4c3D=334q+iWLO>YD%DkVa|d5-Nm`sAL#Eu`OsygW0^^YY9@oR>ck#OgTFCh@54U~1%v z?a>O6x<7F4eG%X9LVRnVJB!>#`+Fh` z^wk7Fx0QkZDFj;eFb}kvfR=TkmchV{ zW$5_WQ3>=1F6gZUK%2`zB_UAhX&$IFngD22Wh0BqLZI?{JW%<|1VB5MEm|}nV6DxO z>;O!?2H3tP>TLoINUjnR)7r)p(>f9-<_W*KvyB Yoshna#nYF0BTnCc9Z+=#E3p5>KZ`ecp#T5? diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/judt/.markers.snap b/.metadata/.plugins/org.eclipse.core.resources/.projects/judt/.markers.snap new file mode 100644 index 0000000000000000000000000000000000000000..b61835500acd60830bb5474a9473236874baa193 GIT binary patch literal 4862 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 VHTfTl+~h7MzR7{C<^y4=H~^s+MBM-Y diff --git a/.metadata/.plugins/org.eclipse.core.resources/6.snap b/.metadata/.plugins/org.eclipse.core.resources/6.snap new file mode 100644 index 0000000000000000000000000000000000000000..3eab6daf073327163f5af89c73fafec90c891602 GIT binary patch literal 795 zcmZ?R*xjhShe1S2b=vdAllRH7Ff%bRfB{n(gocw|AQmGKF)}i+WR<3rFf%bQCuQa_ zGcqtkc*3DB0j_x|0r{DEB`St`$vKI|#X!XjjzA+Bxwt49W;Y{)0J0fbiDijEi$w&X7MmtOj9`!l(m)4+fjYy1h~J;V zo)7%oQ@y+Vm;>>F5dbm*Z(smD6%w49my%k985Hb(6U88oU~B-=u%KvWVBm-ALJtU_ z9#N>CdL%tf=mEipFab3f*!?Elf*8P{2BcxZpifCKM1Tw=KNunz_Cs6*4hCi@y9IAB kL^AA!ssjZBOb;;VP}2kMV2Jqt4q^Z}7@%R#V2BY605JxVQ2+n{ literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs index e371833..ad87d2c 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs @@ -2,6 +2,6 @@ eclipse.preferences.version=1 org.eclipse.debug.ui.PREF_LAUNCH_PERSPECTIVES=\r\n\r\n org.eclipse.debug.ui.user_view_bindings=\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n pref_state_memento.org.eclipse.debug.ui.DebugVieworg.eclipse.debug.ui.DebugView=\r\n -pref_state_memento.org.eclipse.debug.ui.VariableView=\r\n\r\n\r\n +pref_state_memento.org.eclipse.debug.ui.VariableView=\r\n\r\n\r\n\r\n\r\n preferredDetailPanes=DefaultDetailPane\:DefaultDetailPane| preferredTargets=default\:default| diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.egit.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.egit.core.prefs new file mode 100644 index 0000000..3444df2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.egit.core.prefs @@ -0,0 +1,3 @@ +GitRepositoriesView.GitDirectories=E\:\\Study\\java\\judt\\.git; +GitRepositoriesView.GitDirectories.relative=.git; +eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs index c8ae42b..8c08b60 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs @@ -1,3 +1,4 @@ +breadcrumb.org.eclipse.jst.j2ee.J2EEPerspective=true content_assist_disabled_computers=org.eclipse.jdt.ui.textProposalCategory\u0000org.eclipse.recommenders.calls.rcp.proposalCategory.templates\u0000org.eclipse.mylyn.java.ui.javaAllProposalCategory\u0000org.eclipse.jdt.ui.javaAllProposalCategory\u0000org.eclipse.jdt.ui.javaTypeProposalCategory\u0000org.eclipse.jdt.ui.javaNoTypeProposalCategory\u0000org.eclipse.recommenders.chain.rcp.proposalCategory.chain\u0000 content_assist_lru_history= content_assist_number_of_computers=24 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.recommenders.completion.rcp.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.recommenders.completion.rcp.prefs new file mode 100644 index 0000000..b9bd711 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.recommenders.completion.rcp.prefs @@ -0,0 +1,2 @@ +completion_tips_seen=org.eclipse.recommenders.completion.rcp.tips.discovery\:org.eclipse.recommenders.completion.rcp.tips.types +eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs index 6c404ca..23218da 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs @@ -1,5 +1,5 @@ PROBLEMS_FILTERS_MIGRATE=true eclipse.preferences.version=1 -platformState=1502477236593 +platformState=1507442636466 quickStart=false tipsAndTricks=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs index 24795e0..1c460d8 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs @@ -4,24 +4,24 @@ ColorsAndFontsPreferencePage.expandedCategories=Torg.eclipse.ui.workbenchMisc ColorsAndFontsPreferencePage.selectedElement=Forg.eclipse.jface.textfont ENABLED_DECORATORS=org.eclipse.jst.ws.jaxws.dom.integration.navigator.WebServiceDecorator\:true,org.eclipse.m2e.core.mavenVersionDecorator\:false,org.eclipse.wst.jsdt.chromium.debug.ui.decorators.ChromiumJavaScript\:true,org.eclipse.wst.server.ui.decorator\:false,org.eclipse.cft.server.navigatorDecorator\:true,org.eclipse.datatools.connectivity.sqm.core.internal.ui.explorer.DependencyDecoration\:true,org.eclipse.datatools.connectivity.sqm.core.internal.ui.explorer.ColumnDecoration\:true,org.eclipse.datatools.connectivity.sqm.core.internal.ui.explorer.ForeignKeyDecoration\:true,org.eclipse.datatools.connectivity.sqm.core.internal.ui.explorer.IndexTriggerDecoration\:true,org.eclipse.datatools.connectivity.internal.core.ui.bookmarkDecoration\:true,org.eclipse.datatools.connectivity.internal.core.ui.FilterNodeDecoration\:true,org.eclipse.datatools.connectivity.ui.decorator.contentextension\:false,org.eclipse.datatools.enablement.ingres.ui.providers.decorators.SynonymDecorationService\:true,org.eclipse.datatools.enablement.ingres.internal.ui.providers.decorators.ParameterDecorationService\:true,org.eclipse.datatools.enablement.sybase.asa.proxytabledecorator\:true,org.eclipse.datatools.enablement.sybase.ase.webservicetabledecorator\:true,org.eclipse.datatools.enablement.sybase.systemtabledecorator\:true,org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator\:true,org.eclipse.jdt.ui.override.decorator\:true,org.eclipse.jdt.ui.interface.decorator\:true,org.eclipse.jdt.ui.buildpath.decorator\:true,org.eclipse.jst.j2ee.internal.ui.util.AnnotationIconDecorator_ejb\:true,org.eclipse.jst.j2ee.navigator.internal.J2EEProjectDecorator\:true,org.eclipse.jst.jee.ui.internal.navigator.ejb.BeanDecorator\:true,org.eclipse.jst.jee.navigator.internal.JEEProjectDecorator\:true,org.eclipse.jst.j2ee.internal.ui.util.AnnotationIconDecorator_servlet\:true,org.eclipse.m2e.core.maven2decorator\:true,org.eclipse.mylyn.context.ui.decorator.interest\:true,org.eclipse.mylyn.tasks.ui.decorators.task\:true,org.eclipse.mylyn.team.ui.changeset.decorator\:true,org.eclipse.pde.ui.binaryProjectDecorator\:false,org.eclipse.rse.core.virtualobject.decorator\:true,org.eclipse.rse.core.binary.executable.decorator\:true,org.eclipse.rse.core.script.executable.decorator\:true,org.eclipse.rse.core.java.executable.decorator\:true,org.eclipse.rse.core.library.decorator\:true,org.eclipse.rse.core.link.decorator\:true,org.eclipse.rse.subsystems.error.decorator\:true,org.eclipse.ui.LinkedResourceDecorator\:true,org.eclipse.ui.SymlinkDecorator\:true,org.eclipse.ui.VirtualResourceDecorator\:true,org.eclipse.ui.ContentTypeDecorator\:true,org.eclipse.ui.ResourceFilterDecorator\:false,org.eclipse.wst.jsdt.ui.override.decorator\:true,org.eclipse.wst.json.bower.ui.bower\:true,org.eclipse.wst.json.bower.ui.bowerrc\:true,org.eclipse.wst.json.eslint.ui.ESLint\:true,org.eclipse.wst.json.jshint.ui.jshint\:true,org.eclipse.wst.json.npm.ui.NPM\:true,org.eclipse.wst.server.ui.navigatorDecorator\:true, PLUGINS_NOT_ACTIVATED_ON_STARTUP=org.eclipse.m2e.discovery; -REMOTE_COMMANDS_VIEW_FONT=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +REMOTE_COMMANDS_VIEW_FONT=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; eclipse.preferences.version=1 -org.eclipse.compare.contentmergeviewer.TextMergeViewer=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.debug.ui.DetailPaneFont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.debug.ui.MemoryViewTableFont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.debug.ui.consoleFont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.egit.ui.CommitMessageEditorFont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.egit.ui.CommitMessageFont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.egit.ui.DiffHeadlineFont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.jdt.internal.ui.compare.JavaMergeViewer=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.jdt.internal.ui.compare.PropertiesFileMergeViewer=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.jdt.ui.PropertiesFileEditor.textfont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.jdt.ui.editors.textfont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.jface.textfont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.mylyn.wikitext.ui.presentation.textFont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.pde.internal.ui.compare.ManifestContentMergeViewer=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.pde.internal.ui.compare.PluginContentMergeViewer=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.wst.jsdt.internal.ui.compare.JavaMergeViewer=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.wst.jsdt.ui.editors.textfont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -org.eclipse.wst.sse.ui.textfont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; -terminal.views.view.font.definition=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +org.eclipse.compare.contentmergeviewer.TextMergeViewer=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.debug.ui.DetailPaneFont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.debug.ui.MemoryViewTableFont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.debug.ui.consoleFont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.egit.ui.CommitMessageEditorFont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.egit.ui.CommitMessageFont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.egit.ui.DiffHeadlineFont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.jdt.internal.ui.compare.JavaMergeViewer=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.jdt.internal.ui.compare.PropertiesFileMergeViewer=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.jdt.ui.PropertiesFileEditor.textfont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.jdt.ui.editors.textfont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.jface.textfont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.mylyn.wikitext.ui.presentation.textFont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.pde.internal.ui.compare.ManifestContentMergeViewer=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.pde.internal.ui.compare.PluginContentMergeViewer=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.wst.jsdt.internal.ui.compare.JavaMergeViewer=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.wst.jsdt.ui.editors.textfont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.wst.sse.ui.textfont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +terminal.views.view.font.definition=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.jsdt.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.jsdt.ui.prefs index 4dcdc20..b569421 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.jsdt.ui.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.jsdt.ui.prefs @@ -1,6 +1,6 @@ eclipse.preferences.version=1 fontPropagated=true -org.eclipse.jface.textfont=1|Consolas|14.25|0|WINDOWS|1|-19|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +org.eclipse.jface.textfont=1|Consolas|16.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; org.eclipse.wst.jsdt.ui.editor.tab.width= org.eclipse.wst.jsdt.ui.formatterprofiles.version=11 org.eclipse.wst.jsdt.ui.javadoclocations.migrated=true diff --git a/.metadata/.plugins/org.eclipse.debug.core/.launches/TestClient.launch b/.metadata/.plugins/org.eclipse.debug.core/.launches/TestClient.launch index f4eedbd..5f7b192 100644 --- a/.metadata/.plugins/org.eclipse.debug.core/.launches/TestClient.launch +++ b/.metadata/.plugins/org.eclipse.debug.core/.launches/TestClient.launch @@ -1,14 +1,11 @@ - + - - - - + diff --git a/.metadata/.plugins/org.eclipse.debug.core/.launches/TestRecFiles.launch b/.metadata/.plugins/org.eclipse.debug.core/.launches/TestRecFiles.launch new file mode 100644 index 0000000..0cde40b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.debug.core/.launches/TestRecFiles.launch @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.debug.core/.launches/TestSendFiles.launch b/.metadata/.plugins/org.eclipse.debug.core/.launches/TestSendFiles.launch new file mode 100644 index 0000000..088fde3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.debug.core/.launches/TestSendFiles.launch @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.debug.core/.launches/TestServer.launch b/.metadata/.plugins/org.eclipse.debug.core/.launches/TestServer.launch new file mode 100644 index 0000000..a4b3c77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.debug.core/.launches/TestServer.launch @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml index 7bc696ff185626831a25fb66daaee37ab041db69..60c61e710a2fd22368861874543eb9548cc03a23 100644 GIT binary patch literal 1052 UcmZQz7zLvtFd71*A%GbI00bNW0RR91 literal 652 zcmd6jU2B6d6o#+cUm>|~8rK#kXp3lC16Ie>$*zL6nG01j{3sjb$Is3U=ImgXBNzF4 z&N(lSzIiQj<;<#@i_!opL_lF>DvrF&3=oCe*)7e4_J)70Nlu+phC+)de`Q zHv{wpjfovPU_Js>x#wvmYVp)4kBP&$5)r9EB$14XXZvv=RXI~{y8C4^$r`3$k+e? diff --git a/.metadata/.plugins/org.eclipse.debug.ui/launchConfigurationHistory.xml b/.metadata/.plugins/org.eclipse.debug.ui/launchConfigurationHistory.xml index 9f1b71f..6ec40d8 100644 --- a/.metadata/.plugins/org.eclipse.debug.ui/launchConfigurationHistory.xml +++ b/.metadata/.plugins/org.eclipse.debug.ui/launchConfigurationHistory.xml @@ -2,9 +2,7 @@ - - - + @@ -14,8 +12,7 @@ - - + @@ -25,9 +22,7 @@ - - - + diff --git a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi index c3b6aa5..ce770ce 100644 --- a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi +++ b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi @@ -1,21 +1,21 @@ - - + + activeSchemeId:org.eclipse.ui.defaultAcceleratorConfiguration ModelMigrationProcessor.001 - + - + topLevel shellMaximized - - - - + + + + persp.actionSet:org.eclipse.mylyn.doc.actionSet persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation persp.actionSet:org.eclipse.ui.cheatsheets.actionSet @@ -28,7 +28,6 @@ persp.actionSet:org.eclipse.ui.actionSet.keyBindings persp.actionSet:org.eclipse.ui.actionSet.openFiles persp.actionSet:org.eclipse.wst.jsdt.chromium.debug.ui.actionSets - persp.actionSet:org.eclipse.wb.core.ui.actionset persp.actionSet:org.eclipse.jst.j2ee.J2eeMainActionSet persp.actionSet:org.eclipse.jdt.ui.JavaActionSet persp.actionSet:org.eclipse.debug.ui.launchActionSet @@ -47,8 +46,9 @@ persp.viewSC:org.eclipse.search.ui.views.SearchView persp.viewSC:org.eclipse.ui.console.ConsoleView persp.showIn:org.eclipse.ui.navigator.ProjectExplorer - persp.newWizSC:org.eclipse.jpt.jpa.ui.wizard.newJpaProject - persp.perspSC:org.eclipse.jpt.ui.jpaPerspective + persp.actionSet:org.eclipse.wst.ws.explorer.explorer + persp.newWizSC:org.eclipse.m2e.core.wizards.Maven2ProjectWizard + persp.showIn:org.eclipse.tm.terminal.view.ui.TerminalsView persp.perspSC:org.eclipse.debug.ui.DebugPerspective persp.perspSC:org.eclipse.jdt.ui.JavaPerspective persp.perspSC:org.eclipse.ui.resourcePerspective @@ -69,48 +69,47 @@ persp.newWizSC:org.eclipse.ui.wizards.new.file persp.actionSet:org.eclipse.wst.server.ui.internal.webbrowser.actionSet persp.actionSet:org.eclipse.debug.ui.breakpointActionSet - persp.newWizSC:org.eclipse.m2e.core.wizards.Maven2ProjectWizard - persp.showIn:org.eclipse.tm.terminal.view.ui.TerminalsView - persp.actionSet:org.eclipse.wst.ws.explorer.explorer persp.actionSet:org.eclipse.eclemma.ui.CoverageActionSet - - - Minimized - - - - + persp.showIn:org.eclipse.eclemma.ui.CoverageView + persp.newWizSC:org.eclipse.jpt.jpa.ui.wizard.newJpaProject + persp.perspSC:org.eclipse.jpt.ui.jpaPerspective + + + active + noFocus + + + + - - - - - - + + + + + Minimized + + - + Minimized - Java - noFocus - - - - - - - - - - - - + + + + + + + + + + + - - + + persp.actionSet:org.eclipse.mylyn.doc.actionSet persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation persp.actionSet:org.eclipse.ui.cheatsheets.actionSet @@ -123,124 +122,6 @@ persp.actionSet:org.eclipse.ui.actionSet.keyBindings persp.actionSet:org.eclipse.ui.actionSet.openFiles persp.actionSet:org.eclipse.wst.jsdt.chromium.debug.ui.actionSets - persp.actionSet:org.eclipse.wb.core.ui.actionset - persp.actionSet:org.eclipse.debug.ui.launchActionSet - persp.actionSet:org.eclipse.jdt.ui.JavaActionSet - persp.actionSet:org.eclipse.jdt.ui.JavaElementCreationActionSet - persp.actionSet:org.eclipse.ui.NavigateActionSet - persp.viewSC:org.eclipse.jdt.ui.PackageExplorer - persp.viewSC:org.eclipse.jdt.ui.TypeHierarchy - persp.viewSC:org.eclipse.jdt.ui.SourceView - persp.viewSC:org.eclipse.jdt.ui.JavadocView - persp.viewSC:org.eclipse.search.ui.views.SearchView - persp.viewSC:org.eclipse.ui.console.ConsoleView - persp.viewSC:org.eclipse.ui.views.ContentOutline - persp.viewSC:org.eclipse.ui.views.ProblemView - persp.viewSC:org.eclipse.ui.views.ResourceNavigator - persp.viewSC:org.eclipse.ui.views.TaskList - persp.viewSC:org.eclipse.ui.views.ProgressView - persp.viewSC:org.eclipse.ui.navigator.ProjectExplorer - persp.viewSC:org.eclipse.ui.texteditor.TemplatesView - persp.viewSC:org.eclipse.pde.runtime.LogView - persp.newWizSC:org.eclipse.jdt.ui.wizards.JavaProjectWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewPackageCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewClassCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewEnumCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewAnnotationCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewJavaWorkingSetWizard - persp.newWizSC:org.eclipse.ui.wizards.new.folder - persp.newWizSC:org.eclipse.ui.wizards.new.file - persp.newWizSC:org.eclipse.ui.editors.wizards.UntitledTextFileWizard - persp.perspSC:org.eclipse.jdt.ui.JavaBrowsingPerspective - persp.perspSC:org.eclipse.debug.ui.DebugPerspective - persp.viewSC:org.eclipse.ant.ui.views.AntView - persp.showIn:org.eclipse.egit.ui.RepositoriesView - persp.actionSet:org.eclipse.debug.ui.breakpointActionSet - persp.actionSet:org.eclipse.jdt.debug.ui.JDTDebugActionSet - persp.newWizSC:org.eclipse.jdt.junit.wizards.NewTestCaseCreationWizard - persp.actionSet:org.eclipse.jdt.junit.JUnitActionSet - persp.showIn:org.eclipse.jdt.ui.PackageExplorer - persp.showIn:org.eclipse.team.ui.GenericHistoryView - persp.showIn:org.eclipse.ui.views.ResourceNavigator - persp.showIn:org.eclipse.ui.navigator.ProjectExplorer - persp.viewSC:org.eclipse.mylyn.tasks.ui.views.tasks - persp.newWizSC:org.eclipse.mylyn.tasks.ui.wizards.new.repository.task - persp.viewSC:org.eclipse.tm.terminal.view.ui.TerminalsView - persp.showIn:org.eclipse.tm.terminal.view.ui.TerminalsView - persp.viewSC:org.eclipse.wb.core.StructureView - persp.viewSC:org.eclipse.wb.core.PaletteView - persp.perspSC:org.eclipse.wst.jsdt.ui.JavaPerspective - persp.actionSet:org.eclipse.eclemma.ui.CoverageActionSet - - - - org.eclipse.e4.primaryNavigationStack - - - - - - - - - - - - - - - - org.eclipse.e4.secondaryDataStack - Java - Minimized - active - noFocus - - - - - - - - - - - - - - - Minimized - - - - org.eclipse.e4.secondaryNavigationStack - Minimized - - - - - - - - - - - persp.actionSet:org.eclipse.mylyn.doc.actionSet - persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation - persp.actionSet:org.eclipse.rse.core.search.searchActionSet - persp.actionSet:org.eclipse.search.searchActionSet - persp.actionSet:org.eclipse.ui.edit.text.actionSet.annotationNavigation - persp.actionSet:org.eclipse.ui.edit.text.actionSet.navigation - persp.actionSet:org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo - persp.actionSet:org.eclipse.ui.externaltools.ExternalToolsSet - persp.actionSet:org.eclipse.ui.cheatsheets.actionSet - persp.actionSet:org.eclipse.ui.actionSet.keyBindings - persp.actionSet:org.eclipse.ui.actionSet.openFiles - persp.actionSet:org.eclipse.wst.jsdt.chromium.debug.ui.actionSets - persp.actionSet:org.eclipse.wb.core.ui.actionset persp.actionSet:org.eclipse.debug.ui.launchActionSet persp.actionSet:org.eclipse.debug.ui.debugActionSet persp.viewSC:org.eclipse.debug.ui.DebugView @@ -250,3504 +131,3210 @@ persp.viewSC:org.eclipse.ui.views.ContentOutline persp.viewSC:org.eclipse.ui.console.ConsoleView persp.viewSC:org.eclipse.ui.views.TaskList - persp.viewSC:org.eclipse.ant.ui.views.AntView - persp.viewSC:org.eclipse.datatools.sqltools.result.resultView - persp.perspSC:org.eclipse.datatools.sqltools.sqleditor.perspectives.EditorPerspective persp.actionSet:org.eclipse.ui.NavigateActionSet persp.actionSet:org.eclipse.debug.ui.breakpointActionSet persp.viewSC:org.eclipse.pde.runtime.LogView - persp.showIn:org.eclipse.egit.ui.RepositoriesView - persp.actionSet:org.eclipse.jdt.debug.ui.JDTDebugActionSet - persp.viewSC:org.eclipse.jdt.debug.ui.DisplayView + persp.perspSC:org.eclipse.wst.xml.ui.perspective persp.perspSC:org.eclipse.jdt.ui.JavaPerspective persp.perspSC:org.eclipse.jdt.ui.JavaBrowsingPerspective persp.actionSet:org.eclipse.jdt.ui.JavaActionSet persp.showIn:org.eclipse.jdt.ui.PackageExplorer - persp.viewSC:org.eclipse.tm.terminal.view.ui.TerminalsView - persp.showIn:org.eclipse.tm.terminal.view.ui.TerminalsView persp.perspSC:org.eclipse.wst.jsdt.ui.JavaPerspective persp.showIn:org.eclipse.wst.jsdt.ui.PackageExplorer - persp.perspSC:org.eclipse.wst.xml.ui.perspective + persp.actionSet:org.eclipse.jdt.debug.ui.JDTDebugActionSet + persp.viewSC:org.eclipse.jdt.debug.ui.DisplayView + persp.showIn:org.eclipse.egit.ui.RepositoriesView + persp.viewSC:org.eclipse.tm.terminal.view.ui.TerminalsView + persp.showIn:org.eclipse.tm.terminal.view.ui.TerminalsView persp.actionSet:org.eclipse.eclemma.ui.CoverageActionSet - - - - - org.eclipse.e4.primaryNavigationStack - - - - - - - - Minimized - - - - - + persp.showIn:org.eclipse.eclemma.ui.CoverageView + persp.viewSC:org.eclipse.datatools.sqltools.result.resultView + persp.perspSC:org.eclipse.datatools.sqltools.sqleditor.perspectives.EditorPerspective + persp.viewSC:org.eclipse.ant.ui.views.AntView + + + + org.eclipse.e4.primaryNavigationStack + Minimized + + + + + - - - - org.eclipse.e4.secondaryNavigationStack + + Minimized + + + + + + + + + + + org.eclipse.e4.secondaryDataStack Minimized - - + + + + + + + + - - - org.eclipse.e4.secondaryDataStack - Java - General - Minimized - - - - - - - - - - + + org.eclipse.e4.secondaryNavigationStack + Minimized + + + - - Minimized - - - + + + + - + View categoryTag:Help - + - View categoryTag:General - - ViewMenu - menuContribution:menu - - - + View categoryTag:Help - - + + org.eclipse.e4.primaryDataStack EditorStack - - - Editor - org.eclipse.jdt.ui.CompilationUnitEditor - removeOnHide - - - - Editor - org.eclipse.jdt.ui.CompilationUnitEditor - removeOnHide - - - - Editor - org.eclipse.jdt.ui.CompilationUnitEditor - removeOnHide - - + - + View categoryTag:General - + active + ViewMenu menuContribution:menu - - menuContribution:popup - popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu - - - menuContribution:popup - popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu - - - menuContribution:popup - popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu - - + menuContribution:popup popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu - + - + View categoryTag:General - + - View categoryTag:Java - - ViewMenu - menuContribution:menu - - - menuContribution:popup - popup:org.eclipse.jdt.ui.TypeHierarchy.supertypes - - - menuContribution:popup - popup:org.eclipse.jdt.ui.TypeHierarchy.subtypes - - - menuContribution:popup - popup:org.eclipse.jdt.ui.TypeHierarchy.typehierarchy - - - menuContribution:popup - popup:org.eclipse.jdt.ui.TypeHierarchy.members - - - + View categoryTag:Java Browsing - + - + View categoryTag:General - + ViewMenu menuContribution:menu - - menuContribution:popup - popup:org.eclipse.ui.views.AllMarkersView - popup:org.eclipse.ui.ide.MarkersView - - - menuContribution:popup - popup:org.eclipse.ui.views.AllMarkersView - popup:org.eclipse.ui.ide.MarkersView - - + - + View categoryTag:General - + View categoryTag:Server - + View categoryTag:Data Management - + View categoryTag:General - + - View categoryTag:General - - ViewMenu - menuContribution:menu - - - menuContribution:popup - popup:org.eclipse.ui.views.ProblemView - popup:org.eclipse.ui.ide.MarkersView - - - menuContribution:popup - popup:org.eclipse.ui.views.ProblemView - popup:org.eclipse.ui.ide.MarkersView - - - menuContribution:popup - popup:org.eclipse.ui.views.ProblemView - popup:org.eclipse.ui.ide.MarkersView - - - menuContribution:popup - popup:org.eclipse.ui.views.ProblemView - popup:org.eclipse.ui.ide.MarkersView - - - menuContribution:popup - popup:org.eclipse.ui.views.ProblemView - popup:org.eclipse.ui.ide.MarkersView - - - menuContribution:popup - popup:org.eclipse.ui.views.ProblemView - popup:org.eclipse.ui.ide.MarkersView - - - menuContribution:popup - popup:org.eclipse.ui.views.ProblemView - popup:org.eclipse.ui.ide.MarkersView - - - + View categoryTag:General - + View categoryTag:General - active - activeOnClose - + ViewMenu menuContribution:menu - - menuContribution:popup - popup:org.eclipse.debug.ui.ProcessConsoleType.#ContextMenu - - + menuContribution:popup popup:org.eclipse.debug.ui.ProcessConsoleType.#ContextMenu - + - + View categoryTag:General - + View categoryTag:General - + - View categoryTag:General - - ViewMenu - menuContribution:menu - - - + View categoryTag:General - + ViewMenu menuContribution:menu - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - - menuContribution:popup - popup:org.eclipse.jdt.ui.outline - - + - + - View categoryTag:Mylyn - - ViewMenu - menuContribution:menu - - - menuContribution:popup - popup:org.eclipse.mylyn.tasks.ui.menus.activeTask - - - menuContribution:popup - popup:org.eclipse.mylyn.tasks.ui.views.tasks - - - menuContribution:popup - popup:org.eclipse.mylyn.tasks.ui.menus.activeTask - - - menuContribution:popup - popup:org.eclipse.mylyn.tasks.ui.views.tasks - - - - - - - View - categoryTag:Java - - ViewMenu - menuContribution:menu - - - menuContribution:popup - popup:org.eclipse.jdt.ui.PackageExplorer - - - menuContribution:popup - popup:org.eclipse.jdt.ui.PackageExplorer - - - menuContribution:popup - popup:org.eclipse.jdt.ui.PackageExplorer - - - menuContribution:popup - popup:org.eclipse.jdt.ui.PackageExplorer - - - menuContribution:popup - popup:org.eclipse.jdt.ui.PackageExplorer - - - - - - - View - categoryTag:Java - - - - - View - categoryTag:Java - - - - - View - categoryTag:General - - - - - View - categoryTag:Ant - - - - - View - categoryTag:Git - - - - - View - categoryTag:Java - - - - - View - categoryTag:Terminal - - - - - View - categoryTag:WindowBuilder - - - - - View - categoryTag:WindowBuilder - - - - - - View - categoryTag:Java - - ViewMenu - menuContribution:menu - - - menuContribution:popup - popup:org.eclipse.jdt.callhierarchy.view - - - menuContribution:popup - popup:org.eclipse.jdt.callhierarchy.view - - - menuContribution:popup - popup:org.eclipse.jdt.callhierarchy.view - - - menuContribution:popup - popup:org.eclipse.jdt.callhierarchy.view - - - menuContribution:popup - popup:org.eclipse.jdt.callhierarchy.view - - - menuContribution:popup - popup:org.eclipse.jdt.callhierarchy.view - - - menuContribution:popup - popup:org.eclipse.jdt.callhierarchy.view - - - menuContribution:popup - popup:org.eclipse.jdt.callhierarchy.view - - - - + View categoryTag:Debug - + ViewMenu menuContribution:menu - - menuContribution:popup - popup:org.eclipse.debug.ui.DebugView - - - menuContribution:popup - popup:org.eclipse.debug.ui.DebugView - - + menuContribution:popup popup:org.eclipse.debug.ui.DebugView - + menuContribution:popup popup:org.eclipse.debug.ui.DebugView - + - + View categoryTag:Debug - + ViewMenu menuContribution:menu - + menuContribution:popup popup:org.eclipse.debug.ui.VariableView.detail - + menuContribution:popup popup:org.eclipse.debug.ui.VariableView - - menuContribution:popup - popup:org.eclipse.debug.ui.VariableView.detail - - - menuContribution:popup - popup:org.eclipse.debug.ui.VariableView - - + - + View categoryTag:Debug - + ViewMenu menuContribution:menu - - menuContribution:popup - popup:org.eclipse.debug.ui.VariableView.detail - - - menuContribution:popup - popup:org.eclipse.debug.ui.BreakpointView - - + menuContribution:popup popup:org.eclipse.debug.ui.VariableView.detail - + menuContribution:popup popup:org.eclipse.debug.ui.BreakpointView - + - + View categoryTag:Debug - + View categoryTag:Debug - - - - View - categoryTag:Data Management - - + View categoryTag:Debug - + + + + View + categoryTag:Java + + View categoryTag:General - - + + + + View + categoryTag:Terminal + + + + + View + categoryTag:Data Management + + + + + View + categoryTag:Ant + + + toolbarSeparator - + - + Draggable - + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + + Opaque + + + Opaque + + + Opaque + + + Opaque + - + toolbarSeparator - + - - Draggable - - + Draggable + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + - + Draggable + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + - + Draggable + + Opaque + + + Opaque + + + Opaque + - + Draggable + + Opaque + + + Opaque + + + Opaque + + + Opaque + - + Draggable + + Opaque + + + Opaque + - + Draggable + + Opaque + + + Opaque + - + toolbarSeparator - + - + Draggable - + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + + Opaque + + + Opaque + + + Opaque + - + toolbarSeparator - + - + toolbarSeparator - + - + Draggable + + Opaque + + + Opaque + - + stretch SHOW_RESTORE_MENU - + Draggable HIDEABLE SHOW_RESTORE_MENU - - + + stretch - + Draggable - + Draggable - - + + TrimStack Draggable - - TrimStack - Draggable - - + - - TrimStack - Draggable - - + TrimStack Draggable - - + + TrimStack Draggable - + TrimStack Draggable - + TrimStack Draggable - - TrimStack - Draggable - - - TrimStack - Draggable - - - TrimStack - Draggable - - + + + TrimStack Draggable - - - - - - - - - - - locale:zh - - - - - - - - - - - - - + + platform:win32 - + + + + + + + + locale:zh + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + locale:zh - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + locale:zh - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + locale:zh - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - locale:zh + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + - - + + - - - - + + - - + + - - + + + - - + + + + - - - + + - - + + + + + + + + + + + + - - - + + - - - - - + + - - - + + + + + - - + + - - + + + - - + + - - - - + + - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + - - - - - + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + - - - + + + + - - - - + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - + + - - - - - - + + + - - - - - - + + + + + - - - + + + - - - - - - - - + + - - - - + + + - - - + + - - + + - - - - + + - - - + + + + - - + + - - - - - - - - + + platform:win32 - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + - - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Editor - + View categoryTag:Ant - + + + + View + categoryTag:Gradle + + + + + View + categoryTag:Gradle + + View categoryTag:Data Management - + View categoryTag:Data Management - + View categoryTag:Data Management - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + + + + View + categoryTag:Java + + View categoryTag:Git - + View categoryTag:Git - + View categoryTag:Git - + View categoryTag:Git - + View categoryTag:Git - + View categoryTag:General - + View categoryTag:Help - + View categoryTag:Debug - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:Java Browsing - + View categoryTag:Java Browsing - + View categoryTag:Java Browsing - + View categoryTag:Java Browsing - + View categoryTag:Java - + View categoryTag:General - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:JPA - + View categoryTag:JPA - + View categoryTag:JavaServer Faces - + View categoryTag:JavaServer Faces - + View categoryTag:Web Services - + View categoryTag:Maven - + View categoryTag:Maven - + View categoryTag:Mylyn - + View categoryTag:Mylyn - + View categoryTag:Mylyn - + View categoryTag:Oomph - + View categoryTag:API Tools - + View categoryTag:Plug-in Development - + View categoryTag:Plug-in Development - + View categoryTag:Plug-in Development - + View categoryTag:Plug-in Development - + View categoryTag:Plug-in Development - + View categoryTag:Code Recommenders - + View categoryTag:Code Recommenders - + View categoryTag:Code Recommenders - + View categoryTag:Code Recommenders - + View categoryTag:Remote Systems - + View categoryTag:Remote Systems - + View categoryTag:Remote Systems - + View categoryTag:Remote Systems - + View categoryTag:Remote Systems - + View categoryTag:Remote Systems - + View categoryTag:Remote Systems - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Team - + View categoryTag:Team - + View categoryTag:Terminal - + View categoryTag:Other - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Help - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Debug - + View categoryTag:JavaScript - + View categoryTag:JavaScript - + View categoryTag:JavaScript - + View categoryTag:JavaScript - + View categoryTag:JavaScript - + View categoryTag:Server - + View categoryTag:XML - + View categoryTag:XML - + View categoryTag:XML - + View categoryTag:XML - + View categoryTag:XML - - - - View - categoryTag:WindowBuilder - - - - - View - categoryTag:WindowBuilder - - - - - View - categoryTag:Gradle - - - - - View - categoryTag:Gradle - - - - - View - categoryTag:Java - - - - glue - move_after:PerspectiveSpacer - SHOW_RESTORE_MENU - - - move_after:Spacer Glue - HIDEABLE - SHOW_RESTORE_MENU - - - glue - move_after:SearchField - SHOW_RESTORE_MENU - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + - - - - - - + + + - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + - - - - - - - - - + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + - - - - - - + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/server-config.json b/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/server-config.json index d5bfaa5..8c00a73 100644 --- a/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/server-config.json +++ b/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/server-config.json @@ -1,10 +1,10 @@ { "version": "v1", "title": "Eclipse", - "timestamp": 1503851957181, + "timestamp": 1507046825572, "ttl": 10080, "helpUrl": "https://dev.eclipse.org/recommenders/community/aeri/v2/help/", - "feedbackUrl": "http://ctrlflow.com/automated-error-reporting", + "feedbackUrl": "https://www.codetrails.com/error-analytics/", "aboutUrl": "https://wiki.eclipse.org/EPP/Logging", "submitUrl": "https://dev.eclipse.org/recommenders/community/confess/0.6/reports/", "maxReportSize": 262144, diff --git a/.metadata/.plugins/org.eclipse.jdt.core/1805218701.index b/.metadata/.plugins/org.eclipse.jdt.core/1805218701.index index 7afa7e9bd6d6263161dee2353213f841228a5b69..e43944dec7aec89a821f10224da4c2b2fd8284d2 100644 GIT binary patch literal 86362 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≦qlVD+1Wlc%G=n z47mPqa~jcC=XXB{icu*44!!uL>v};0)<81mmwH&(Qa%s?D;Z1;F0qzQ@O#yjvw_Sw zbH(;9`RU2uw^WSCCG!FU|GeO>^i1aehr2vz(YL~D1zFw^c% zsHsmCr{L^Hk0O1GOO3V#^r7<1>~^C)XDY@02hkzL?@YgBMl$6s&>XQT7?Gu+0OW`8 zQd{NrjcH~X>xfled3tv2xl2@j7~mT*ely05uG=O4gqU54Z-Rj$uV?zff^LyG7pib_ zc6%p9U;%Z6gAHa8^q=o;A&On@n0u-Lr#gE6u5W*t&jKLy*dhUb@q^wb+}pYv2uU$W4H5uYFAr2jU9|6Ljl7 zCvg|y#ww3YpzE)aT?X<#blW`7dD6sTux=-=|5xeBntHE5 z`e1Rt{FV5$%@)vlb{Nx`s@uVb-DWTD)`9yNYR6AcO`Z@`y_}&;SIep{8CVgo)+%Nz zM-Wpw&dcbEW(qf?H@wT*%$#fA(;CL+Y?~20i1+-mH~#EPnnS}sVYoDf&4hXDK0k9! z#A3Zfz)m=G4%V|r@Oi7?~Ip)l-!Z10c%J<#i+FnC{SA%RHfdZ!7KsH=<17SA_ ztv5P$k&O(#gcabNh$fKwS>QGii(CTf5ZcWUOD>6jwH^nVMTuSxy-;1 z4#HvK2!QTgkfn`YE!lYfWG5+05~D5QmeiQ+wr#$UEd zXF?nDb!GGxiDVf{@GXPivH8367RXfB`$Bc@d`c?t_*ZTy%;%2S2-7kECKxwQE>bp| z1;QG&Vjn`LvDVpwkTe*gV^v%iO6)?nL9e;j%%M_?s1uIrV?K_vItwEJc`Zz3N>M^Z z3^y0aP(xNIr8;}wK2kf6_PWhx2uV>>q6o1^!xRP+(vk!=VAL=FaD5PAWT}}0v+C8H zdzl%J&gvH*>HzCiTTG01@E8r-Ul2uDde3`f6tIMmO0CMthVT0zvcUsO@(x&1$EL%Q zyA=2;xU}V@9P3;04Tzg9EoQj+rrl&XOJ6HpJ8$349be0>kuWerd8XK@8+$Z%CZiV-|egSV|O8MiRRmym3sATonP+mi~YbtG1AN zC7uM*D3y)nv**0dfaf6%y$YM>ckDGA6QtQ<&8OSbx3dD3#95>x`&AdW%~Vp{U>Yf% zfIAws;H_WMPHo|Gkqx-sd52FGLqhHtQ!DpCp;}N6Z-t8&8lG2;r=ObSDoi6)OHos? zSR!Bj9?0}=ZHP_Ca<=_Q*lTX6@IpzfA>ILI2aBR!?WRJwB;FtXRocypH?Fw|#N?}U zTN7nd5VbSU)R3?&3k~rf_+KV>@%}L2RUVrT&oOj(eT;*yD{1$Z?^P~-;PWkUiVi?j z+o^m@-gbI`#n^52@H;H-Xqgo=GpOi~-6pZU;nLg^gp3Wtav$oa;PAe?x$7e^JLG{m zc)f}f^=d;A?LP<^q_iXR)#JWJZOHQMS2h5qGi){0%9Zy33kx7joElV3fji@!TQ(&F z@7$fn-lm|}U3{h{Fce2T8&-arQzWC`+08ZOH{Kq$F^Vx?BLZGU;gI)JeRN*lzClH~ zjD|@`=|8!sgdWb7G>BTQV9JF@oUdAn7v2U-QS1{^kuoLcuf*nqSCT0!RQog6h3W&0 zGx2mpeo?NBlt`hewb2$^L7K}K=^ HvH#+~1kPaK literal 77082 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 H#ZCPm-cQW( diff --git a/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache b/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache index da20993570199afe7c915055dc28ce12c3e00181..593f4708db84ac8fd0f5cc47c634f38c013fe9e4 100644 GIT binary patch literal 4 LcmZQzU|;|M00aO5 literal 812 zcma)(O-{ow5QTk)UIAEuNQ|WxA=ccZnvN&LZg8v_x2iZjiCwX@v;XGJ`%y~m)Wg@O z_Hcy=Y1E#{^dJ4((HNsAcha1C53HW65RSk?Niy11QMx6KlVuADGXC1c1IRdY$h2BA!(BhOc7sVvh@x?B-vH&4|MUZf0jsA8+>vUPW2 LXTPa?->>R_#&-lT diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps b/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps index 57047c10a1feb061853f8efd5c8bfcb82528e411..a76b12cde7642eb5ad004270cc5d2101a20dfbcd 100644 GIT binary patch delta 263 zcmdnPzK4B+E_>XsBvU;G<%x;1d_^UCS&2mq42*Gq7qawEj5lVD`<3ukck)I?<%zp^ zfGQJuZ5cFyDkr|;2lD!^E@Uv7n5Z&Yg;5yDP1$^z!E|Dx;^cTnaUeI@JDfoW#GS{; z2Q(*9>M+n8efGHDW!HB?BsiEr67^nxodXFR|Zv}>dDs3+(2$-=1T^BkZc~a WAkc;;<;;okYLizn^8z_3&Q1XRg{yUZJ%N$`cc1`HD*PvJ#6J7#L%(o_<$7G2WOp_EPsrr^y=`l_&1v z0jlgySjwOYR5|e#KajU`|8fSCiHRzcRTzbV-2T2L45kwk6(`3tiUYZQvPT$nK-_tZ zd?0h)EdrXO&mMbu;hIYj2@WQZ#47nmKneNDR!jmw-ho+nLDmUZWfr6r!(4NzC+r-9 z3eaButh6Gy;N+WICvRi|ns}-EwG)Fb$SMwIkh_kl|6))Ds-A4k%njsD3I52S50cGe X76jU`mN$E1yxQbd%)CHOzq}6s5O85v diff --git a/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt index 9954f27..36fe9a7 100644 --- a/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt +++ b/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt @@ -12,8 +12,8 @@ INDEX VERSION 1.130+E:\Study\java\judt\.metadata\.plugins\org.eclipse.jdt.core 3509802008.index 1805218701.index 1192406101.index -3268650884.index 2973984958.index +3268650884.index 3931001268.index 1829136339.index 3566617508.index diff --git a/.metadata/.plugins/org.eclipse.jdt.debug.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.debug.ui/dialog_settings.xml index 32d5440..5ca0b77 100644 --- a/.metadata/.plugins/org.eclipse.jdt.debug.ui/dialog_settings.xml +++ b/.metadata/.plugins/org.eclipse.jdt.debug.ui/dialog_settings.xml @@ -1,9 +1,3 @@
-
- - - - -
diff --git a/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml b/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml index 1ad9277..eb442b5 100644 --- a/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml +++ b/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml @@ -1,5 +1,5 @@ - + diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml index 71a75b6..d9d780c 100644 --- a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml +++ b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml @@ -1,71 +1,7 @@
- - - - - - - - -
-
-
- - - - -
-
- - - - - -
-
- - -
-
- -
-
- - - -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - -
-
-
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png new file mode 100644 index 0000000000000000000000000000000000000000..269f575e1b0d50dbfb351b86b323742ce47cdddb GIT binary patch literal 534 zcmV+x0_pvUP)e@7ZiuPEZh*`w%}H{%Ys9pP7A6-9p+1*tHl6e&hz4d8ong?FaKVaw)uZm z*4F<8@$3J``z-w)<~;vbsPlqkoSH+O=QT#SF8o=Oz4ia3=EE4cJbm+jpaH+b92W#* zYIc}!5b8Ale?$IGu;P#JzoX!rS6+d|D>JtI4|7@g5yLxS&I^{Og{=J3QMva&2rrp= z_CE}qKJw`QC+VSfpK&34!8k3)?b5*gK$>(s{cS2zd`rHlLX%-|5JmOfpJB~ zMz{f+R$PLMgK(VpVqjp-e~#vb`5U6#7Xtma7>tXP*TW51zw9Dh9E2m?7W@fuTCg0& zfDp%d{=k6wmE^w^Y|FbhU*QIP{qpnwslyMz;z@o>fzF@*H^gPW17;!uni}D@@MlKo z%Kx>wTTyUD#-{&iAuIle1Jg+uy6uRxFqJ3VY5q}Qc>GBUSoS|FV%7g#V2FbPHz{B_ z$lrf}wl4vx!)gEsI5;%0ggDPj4|AD+0~9kL4Ak@`%w@rmP{#${I5pyO5h!Dkq-j6^ Y0R1m@T%fU|{Qv*}07*qoM6N<$f;`Uz`Tzg` literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png new file mode 100644 index 0000000000000000000000000000000000000000..a839ceb0e95c38b180ed346a05106e06eac5e1e7 GIT binary patch literal 345 zcmV-f0jB%fB&S+$&;ra0^%1_rp(wkVZ!8KqBJ%%G_XvbJoVt5IrG2l*|Ycmv17;o@7}%V z|BM;4KTn!8Z3RICdV437&zw2?^Zxw@{)51Q0|&tv#GgEQ+UMTh{v^BxbawVVT()fG z|8?s&fDHiAFuZv2vj0H&(|8SNYHI&KckTi(1_2lwglEl~_rJNh{UcrjYU^6w_4Q5q zKViZYumK<%hI@J^{;#WRxrNt&nwo}%t!-UDfT8~%8G!hWO>JK)s_Lro8c^9L~c{!g1W3#fU<|Axl4@1vTmCFi?D!vsJSAH)ns{CA3 rR5>FntAU50W^_0eK*0TzG1|M-7K%JKi5#G3z?j6y-0zXP!fPEBV`Y;T-1wtIiU&iw<3 ze!us?GmxzyzkfV%3S>Y#UR%$b*nj>pYu5k2FJAorK4ZrJ^Onx-SO1SB8F1dv=JV&4?*D&*hJ3DV{eRxv`2$G?oHek1cfr#6^Hu-IFChAi hk@XFd3>XE(0|36P+SAm8R2TpN002ovPDHLkV1gSpiyQy| literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png new file mode 100644 index 0000000000000000000000000000000000000000..69ec8b91228016877c829792d01a49798cc70383 GIT binary patch literal 319 zcmV-F0l@x=P)R8Y)ekoS9Z+fj6Uhc3Ip2zC%~)LU4~ThiD&}nPl;LgmUd-R-^ALo2 zTYP4t8NiHFGe?7m0(Xn|ThDnZzgo7}{4ZQz@?U#Ws!jw%>VW4i%@XJvh4rd&EC%m8o<`*`8#-e^#912F(}w|a`=Ca zCeP0V4d80>I-}R^|KDR`FbbAw^ZCco>rD*%A2>hZf5gJ1|K?L7 z{{p@Cg{{F&gP;LmL+U*(xLbWLvo(7C1z{ljJjh_8G^2n92Oc2iAYCIp0RU1v=vrJ* R@>c)=002ovPDHLkV1oF(k=g(N literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/12.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/12.png new file mode 100644 index 0000000000000000000000000000000000000000..1c09643cbe6dedae7fa565b2e2d004681177588d GIT binary patch literal 310 zcmV-60m=S}P)W3nn?Lv~Ho{`&3i^#A{#0P&-V5d37; z|Bu&u|L>fv{*AEnr|NwEd9(Nb|CCS?Al& zs~!LUU8(&4?`qBeFBhBsZ|hV0zNt&8kf?Cj*rhUM=On#vKW@$X|K-}`|66+0zi((K zQZo#!YgL-ExmWA+h7OglYnl~E(+mU48x$1QHb~2mrI~I304rmW!}(UI*8l(j07*qo IM6N<$g8bN~eE7JdGsQm_rAN0p-%=`}o->%>Le^D>+|0Sc){~z|A015qvYiw|E zV3`o7UOq8i{qN!`@86pzX8+$YqxAo}uH^soik*Lh6oWMX`TX_&*UPuTY!m|~Bxuf> zoUHeA%jCTOhn9C@U=TPX!~b|2ZXhFn+Ug zJF)?4Px|B3{=+Z~EGYN*4|3V;JX@f+I#>><_W#5B_3cb#H;0{b6CPfIoW0}=-s&WC*lIN k$4>lW^JME`dc?@^aGBGW6W&)Q0G-0%>FVdQ&MBb@0GJq3#sB~S literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/15.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/15.png new file mode 100644 index 0000000000000000000000000000000000000000..38a7305dbef139708f706886133408999c10a79a GIT binary patch literal 563 zcmV-30?hr1P)7JdGsQm_rAN0p-%)D`IWB84i_x>An1^oZ?%8mTs^ez|I}2&{~+)7#j2a2CqRY?vFg(%CTRVbk!AjWWpnudl`WC~m(&LQUkb%@ ziX8q=h}ZZDG+-)*W)PSfs?7sTva5l~`0vzo!@sj~tib*U(bH0m{(!`R1~h_FELHu{~;MF*E0RUy_#}BNASswrZ002ovPDHLkV1gs- BB>4aU literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png new file mode 100644 index 0000000000000000000000000000000000000000..5a8a6f0ab948980349812606d6d4d0d177900b79 GIT binary patch literal 294 zcmV+>0oneEP)l43gQrLTkDM8Uf?X$v|L17({7ldQt|qTDdfop2JthXDV3{_be;iF- zy9gS<+TdjXwCTIv#IXN?^Ar9@EKK@uJ|*%m&}(1V8r(Dp8UQw=-qV7+)#ox>qt{;$ s2C~nC3?@o53TSZP0b&l)HPRCR0K3q4c#baq_5c6?07*qoM6N<$f{|i}+yDRo literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png new file mode 100644 index 0000000000000000000000000000000000000000..a184bb230eba304dfdfdcf6c07fa2cc0bf149114 GIT binary patch literal 307 zcmV-30nGl1P)-SO1SB8F1dv=JV&4?*D&*hJ3DV z{eRxv`2$G?oHek1cfr#6^Hu-IFChAik@XFd3>XE(0|23QJ;Xz?+w}kd002ovPDHLk FV1gULk`({| literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png new file mode 100644 index 0000000000000000000000000000000000000000..ba2d4d6937f1665c771d4ee5b48e52939d7fb438 GIT binary patch literal 412 zcmV;N0b~A&P){^zHkU;aM(^z#3gA735Z`B+?|uCBUo)ul|E1@j{vW*c`oDVe z983eihSYmnaJTwgW^45N3&NTSv;I%tdHMhOryu{PcC7!O)wAh;{j%f#UCWkZHvkSA z9C(13W6tJt|1GoT|DV6_`u`L6-uy3~w)?+c!i@jBPTeJ702F{id+z45|8*iK{g?Ic u{;wZ9<^P6**RaO|E(2iT%eSA%-2VWK6bdLxY4uM40000)Za>=fC^YsKR_sDq{ccgqMGQuBv|`E>L^y#4k2awjQQOj0~1`TSISd RnFMk;gQu&X%Q~loCIGf)U%mhU literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png new file mode 100644 index 0000000000000000000000000000000000000000..588e908a5a29c61c35c9ff6069293e9e51a7c061 GIT binary patch literal 411 zcmV;M0c8G(P)VM_tK9B*=ftZC@1F}DU|NLLC)Bpdq7kB4Ijj zZz)SN|JScCLctl!vj1~8dp{=_U~G+^zk{bo|Bsv*gMwWrhyUkj^88HD0InvlGkV?r z|2-xKqhOgfpMM-pUb_eyz}nzt0JQ15-o&u~f%6moM=VVGZ$2gRFVJgW*c#k42pRx3 zq~6nlyVd71Tcg)s5C*c(gA680GYV*M-~nO|(lyc(002qS6Xq-N*Mk56002ovPDHLk FV1hwF&JX|q literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png new file mode 100644 index 0000000000000000000000000000000000000000..7b019ba3141a122d127bba926065fd5f29443496 GIT binary patch literal 635 zcmV->0)+jEP)xb-+SBKM)sJw|P0#l3+q>_5p7&T%l7~`9)$THm zbna+XzL0YyUEZRcmAOb*++4LQKUN5jYKx2|93`#Q^;&+rhitey(tr!`dKh|)Kcy}v zCuNDdC|}Mg`}TUZYu854pgY-!2QR%yq{8Tb$w!JKkek-4NT5VL4Cu3JsvG2 zF6N$a1`g(68K=x>f`@VGA&Ye8i(m_LU*~Z=X2brQ21x0=M9tNen^sB7idVEB$ZA7I zm}6FWhI|M=kD+bQ3thwl4Q+Af74>(Ty|3UQi5pd0B`is9Z&7Be0(xk>P0-ysf|`g4 z`}{h{I3`0|4Q*U(K>;50v(!<2ik@_8V>6VHrS^@IpNSm`MR8&g$Q>%tKa>7D{s7)i VUb5A`L(~8O002ovPDHLkV1kumFv9=< literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png new file mode 100644 index 0000000000000000000000000000000000000000..be086d7a548e6926e48bd63c76f6ba3ada5f3209 GIT binary patch literal 333 zcmV-T0kZyyP)WWd$r{j_;&&;R#dKm333;l=;_HFf_vnmq3k zZ2)JZce!+@-?ye6eg898Rs9!f^Zm@y=uuC!0SpZeJZz0Vi`bjIzH_(u++%O_%mj+D f5O2UJAPE2fb!<9{H5{K500000NkvXXu0mjf4m*~u literal 0 HcmV?d00001 diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/judt/2017/10/41/refactorings.history b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/judt/2017/10/41/refactorings.history new file mode 100644 index 0000000..05b6d2d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/judt/2017/10/41/refactorings.history @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/judt/2017/10/41/refactorings.index b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/judt/2017/10/41/refactorings.index new file mode 100644 index 0000000..b8ad2d5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/judt/2017/10/41/refactorings.index @@ -0,0 +1,4 @@ +1507451177753 Infer generic type arguments +1507630373385 Delete element +1507630378761 Delete element +1507631173940 Delete elements diff --git a/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml index 6b45f590187c5675a0b442e0691b2b27d4306cd9..9ed29b5a90eabbd490110a054e71ae6bcc9eeefb 100644 GIT binary patch literal 7324 zcmeIuF#!Mo0K%a4Pi+c6h(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxdf&ah& D9Gn0F literal 6879 zcmcgxOK;;g5I%Q*h2a9Z)k$Bw1(Iw~wCH)!HrOLUlOu^WMQTaPj`!DhDAKkR({aku zxmcDZb2#68^W@#bQ!8g{Fji=FKmUGlGoOKCnhRCm&maH( zrNi~%s&=^K79Uq>!ox?S3-i_Z$7;HL%6)~kJ(Bn9wq!HfvU&uQ&=nfHRu?= zv)(%0#@}}+h1(YdS#S>Vn~9wm=Ed~gqSB_Nj#%9r1_V)t-O>Yk;ijU}#^0|~YMfl1 zX@y&Kr0UgREGmgm4opQE*ph-M=cE=q=H~iQow$Ws7R*3dkB!q)Q1A(cmzo5{k-_ zvc{end?jVGY*nb-(5)q>yt5J@cg|T-tLTf)P$4}RHw~s7+xf6YM6I*|0&V9~?w_qH z)98@QyCz3h9PCw6B?U;f0mzOT6wrY6$|wR)oxxyMIG%c5T$JSLaCw@7xnbk2spsV_ zrDm&`ZG1j5;CiDl^I^Qku(>J8i&HrIXkFHoM>!l5oiT!A<~byD) zHHI!?+(BaLmpwuL)xpEpMN}+d{e=wEc1@c`scJCg{tkO;*6U zk>HHR7cO_b!T(dH&!*NMN)&l$Tn7Is848BLiW=cO0P_SkYNbors0VgMJx&FbyI^k= zMWyP?k|Aws8PRsy6lJ*Q7{z9J+v?tihK(=-#cNk>YO2InAg5KxX0Js|u;3_O?nLZ& zeLRjzuo~!@)5)qTH^%HHFisOtm>3y)psyIE)?G;^jjD`LoF*2})#1>YoLoBFx}Kqu zwo6V6Zg>R7+eBEe#o6IhLcwgYtj6@1EJ`59hNLZ13lowiYg{QCK+#$dbi%Xmw1 z93<*`y43XWc)k=Uq^{vkE!r62-2-Q2 + + + %date [%thread] %-5level %logger{35} - %msg%n + + + OFF + + + + + ${org.eclipse.m2e.log.dir}/0.log + + ${org.eclipse.m2e.log.dir}/%i.log + 1 + 10 + + + 100MB + + + %date [%thread] %-5level %logger{35} - %msg%n + + + + + + WARN + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties b/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties index f2bca2f..6b42b24 100644 --- a/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties +++ b/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties @@ -1,2 +1,2 @@ #Cached timestamps -#Mon Aug 28 00:54:45 CST 2017 +#Tue Oct 10 23:09:39 CST 2017 diff --git a/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647106718.target b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647106718.target new file mode 100644 index 0000000..4cddeb2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647106718.target @@ -0,0 +1,12 @@ + + + + + + +win32 +win32 +x86_64 +zh_CN + + diff --git a/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647150848.target b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647150848.target new file mode 100644 index 0000000..4cddeb2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647150848.target @@ -0,0 +1,12 @@ + + + + + + +win32 +win32 +x86_64 +zh_CN + + diff --git a/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647262388.target b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647262388.target new file mode 100644 index 0000000..4cddeb2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647262388.target @@ -0,0 +1,12 @@ + + + + + + +win32 +win32 +x86_64 +zh_CN + + diff --git a/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647315540.target b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647315540.target new file mode 100644 index 0000000..4cddeb2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647315540.target @@ -0,0 +1,12 @@ + + + + + + +win32 +win32 +x86_64 +zh_CN + + diff --git a/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647349336.target b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647349336.target new file mode 100644 index 0000000..4cddeb2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507647349336.target @@ -0,0 +1,12 @@ + + + + + + +win32 +win32 +x86_64 +zh_CN + + diff --git a/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507648147331.target b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507648147331.target new file mode 100644 index 0000000..4cddeb2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.pde.core/.local_targets/1507648147331.target @@ -0,0 +1,12 @@ + + + + + + +win32 +win32 +x86_64 +zh_CN + + diff --git a/.metadata/.plugins/org.eclipse.pde.core/SavedExternalPluginList.txt b/.metadata/.plugins/org.eclipse.pde.core/SavedExternalPluginList.txt new file mode 100644 index 0000000..b375747 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.pde.core/SavedExternalPluginList.txt @@ -0,0 +1,1001 @@ +# List of external plug-in models previously loaded. Timestamp: 1507648179376 +file:/C:/Users/jinyu/.p2/pool/plugins/ch.qos.logback.classic_1.0.7.v20121108-1250.jar +file:/C:/Users/jinyu/.p2/pool/plugins/ch.qos.logback.core_1.0.7.v20121108-1250.jar +file:/C:/Users/jinyu/.p2/pool/plugins/ch.qos.logback.slf4j_1.0.7.v201505121915.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.google.gson_2.7.0.v20170129-0911.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.google.guava_21.0.0.v20170206-1425.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.google.guava_15.0.0.v201403281430.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.google.inject_3.0.0.v201312141243.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.google.inject.multibindings_3.0.0.v201402270930.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.google.javascript_0.0.20160315.v20161124-1903.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.google.protobuf_2.4.0.v201105131100.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.gradleware.tooling.client_0.19.3.v20170801075239.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.gradleware.tooling.model_0.19.3.v20170801075239.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.gradleware.tooling.utils_0.19.3.v20170801075239.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.ibm.icu_58.2.0.v20170418-1837.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.jcraft.jsch_0.1.54.v20170116-1932.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.sun.el_2.2.0.v201303151357.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.sun.jna_4.1.0.v20170410-1117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/com.sun.jna.platform_4.1.0.v20170410-1117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/java_cup.runtime_0.10.0.v201005080400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javaewah_1.1.6.v20160919-1400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.activation_1.1.0.v201211130549.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.annotation_1.2.0.v201602091430.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.el_2.2.0.v201303151357.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.inject_1.0.0.v20091030.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.jws_2.0.0.v201005080400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.mail_1.4.0.v201005080615.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.persistence_2.1.0.v201304241213.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.servlet_3.1.0.v201410161800.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.servlet.jsp_2.2.0.v201112011158.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.wsdl_1.6.2.v201012040545.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.wsdl_1.5.1.v201012040544.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.xml_1.3.4.v201005080400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.xml.rpc_1.1.0.v201209140446/ +file:/C:/Users/jinyu/.p2/pool/plugins/javax.xml.soap_1.2.0.v201005080501/ +file:/C:/Users/jinyu/.p2/pool/plugins/javax.xml.stream_1.0.1.v201004272200.jar +file:/C:/Users/jinyu/.p2/pool/plugins/javax.xml.ws_2.1.0.v200902101523.jar +file:/C:/Users/jinyu/.p2/pool/plugins/net.sourceforge.lpg.lpgjavaruntime_1.1.0.v201004271650.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.ant_1.10.1.v20170504-0840/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.axis_1.4.0.v201411182030/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.batik.css_1.8.0.v20170214-1941.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.batik.util_1.8.0.v20170214-1941.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.batik.util.gui_1.8.0.v20170214-1941.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.bcel_5.2.0.v201005080400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.codec_1.9.0.v20170208-1614.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.collections_3.2.2.v201511171945.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.compress_1.6.0.v201310281400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.discovery_0.2.0.v201004190315/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.httpclient_3.1.0.v201012070820.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.io_2.2.0.v201405211200.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.jxpath_1.3.0.v200911051830.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.lang_2.6.0.v201404270220.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.lang3_3.1.0.v201403281430.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.logging_1.1.1.v201101211721.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.logging_1.0.4.v201101211617.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.math_2.1.0.v201105210652.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.net_3.2.0.v201305141515.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.commons.pool_1.6.0.v201204271246.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.felix.gogo.command_0.10.0.v201209301215.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.felix.gogo.runtime_0.10.0.v201209301036.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.felix.gogo.shell_0.10.0.v201212101605.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.felix.scr_2.0.10.v20170501-2007.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.httpcomponents.httpclient_4.5.2.v20170210-0925.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.httpcomponents.httpclient.win_4.5.2.v20170410-1149.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.httpcomponents.httpcore_4.4.6.v20170210-0925.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.jasper.glassfish_2.2.2.v201501141630.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.log4j_1.2.15.v201012070815.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.lucene.analyzers-common_6.1.0.v20161115-1612.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.lucene.analyzers-smartcn_6.1.0.v20161115-1612.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.lucene.core_6.1.0.v20161115-1612.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.lucene.core_3.5.0.v20120725-1805.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.lucene.misc_6.1.0.v20161115-1612.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.lucene.queryparser_6.1.0.v20161115-1612.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.maven.resolver.api_1.0.3.v20170405-0725.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.maven.resolver.connector.basic_1.0.3.v20170405-0725.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.maven.resolver.impl_1.0.3.v20170405-0725.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.maven.resolver.spi_1.0.3.v20170405-0725.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.maven.resolver.transport.file_1.0.3.v20170405-0725.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.maven.resolver.transport.http_1.0.3.v20170405-0725.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.maven.resolver.util_1.0.3.v20170405-0725.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.solr.client.solrj_3.5.0.v20150506-0844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.velocity_1.5.0.v200905192330.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.ws.commons.util_1.0.1.v20100518-1140.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.wsil4j_1.0.0.v200901211807.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.xalan_2.7.1.v201005080400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.xerces_2.9.0.v201101211617.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.xml.resolver_1.2.0.v201005080400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.xml.serializer_2.7.1.v201005080400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.apache.xmlrpc_3.0.0.v20100427-1100.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.aether.maven_3.1.0.v20140706-2237.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ant.core_3.5.0.v20170509-2149.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ant.launching_1.2.0.v20170509-2157.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ant.ui_3.7.0.v20170412-1054.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.buildship.branding_2.1.2.v20170807-1324.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.buildship.core_2.1.2.v20170807-1324.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.buildship.stsmigration_2.1.2.v20170807-1324.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.buildship.ui_2.1.2.v20170807-1324.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cdt.core.native_5.10.0.201709131603.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cdt.core.win32_5.4.1.201709131603.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cdt.core.win32.x86_64_5.4.1.201709131603/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cft.server.branding.core_1.0.2.v201709130027.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cft.server.branding.ui_1.0.2.v201709130027.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cft.server.core_1.2.3.v201709130027.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cft.server.rse_1.0.1.v201709130027.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cft.server.standalone.core_1.0.4.v201709130027.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cft.server.standalone.ui_1.0.4.v201709130027.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cft.server.ui_1.0.110.v201709130027.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.cft.server.verify.ui_1.0.1.v201709130027.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.compare_3.7.101.v20170724-1603.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.compare.core_3.6.100.v20170516-0820.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.compare.win32_1.2.0.v20170517-0839.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.commands_3.9.0.v20170530-1048.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.contenttype_3.6.0.v20170207-1037.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.databinding_1.6.100.v20170515-1119.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.databinding.beans_1.4.0.v20170210-0856.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.databinding.observable_1.6.100.v20170515-1119.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.databinding.property_1.6.100.v20170515-1119.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.expressions_3.6.0.v20170207-1037.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.externaltools_1.1.0.v20170113-2056.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.filebuffers_3.6.100.v20170203-1130.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.filesystem_1.7.0.v20170406-1337.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.filesystem.win32.x86_64_1.4.0.v20140124-1940.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.jobs_3.9.1.v20170714-0547.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.net_1.3.100.v20170516-0820.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.net.win32.x86_64_1.1.0.v20160323-1650.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.resources_3.12.0.v20170417-1558.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.resources.win32.x86_64_3.5.100.v20170516-0925.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.runtime_3.13.0.v20170207-1030.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.core.variables_3.4.0.v20170113-2056.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.common.doc.user_1.7.0.20090521092446.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity_1.14.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.apache.derby_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.apache.derby.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.apache.derby.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.console.profile_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.db.generic_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.db.generic.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.dbdefinition.genericJDBC_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.doc.user_1.7.0.20090521092446.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.doc.user.contexts_1.7.0.20090521092446.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.oda_3.6.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.oda.consumer_3.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.oda.design_3.5.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.oda.design.ui_3.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.oda.flatfile_3.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui_3.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.oda.profile_3.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.oda.template.ui_3.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.sqm.core_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.sqm.core.ui_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.sqm.server.ui_1.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.ui_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.connectivity.ui.dse_1.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.doc.user_1.7.0.20090521092446.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.finfo_1.7.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.hsqldb_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.hsqldb.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.hsqldb.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2.iseries_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2.iseries.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2.iseries.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2.luw_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2.luw.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2.luw.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2.zseries_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2.zseries.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.db2.zseries.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.informix_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.informix.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.informix.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ibm.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ingres_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ingres.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.ingres.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.jdt.classpath_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.msft.sqlserver_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.msft.sqlserver.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.msft.sqlserver.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.mysql_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.mysql.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.mysql.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.oda.ws_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.oda.ws.ui_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.oda.xml_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.oda.xml.ui_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.oracle_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.oracle.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.oracle.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.postgresql_1.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.postgresql.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.postgresql.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sap.maxdb_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sap.maxdb.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sap.maxdb.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sqlite_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sqlite.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sqlite.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.asa_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.asa.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.asa.models_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.asa.schemaobjecteditor.examples_2.7.0.200810071.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.asa.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.ase_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.ase.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.ase.models_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.ase.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.models_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.enablement.sybase.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.help_1.7.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.intro_1.7.0.v201005281800.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.modelbase.dbdefinition_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.modelbase.derby_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.modelbase.sql_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.modelbase.sql.edit_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.modelbase.sql.query_1.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.modelbase.sql.query.edit_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.modelbase.sql.xml.query_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.oda.cshelp_1.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.common.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.data.core_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.data.ui_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.db.derby_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.db.derby.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.db.generic_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.db.generic.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.ddlgen.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.debugger.core_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.debugger.core.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.doc.user_1.7.0.20090521092446.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.doc.user.contexts_1.7.0.20090521092446.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.editor.core_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.editor.core.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.parsers.sql_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.parsers.sql.lexer_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.parsers.sql.query_1.4.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.parsers.sql.xml.query_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.plan_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.result_1.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.result.ui_1.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.routineeditor_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.routineeditor.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor_1.3.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui_1.3.0.200810071.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages_1.3.0.200810071.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.sql_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.sql.ui_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.sqlbuilder_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.sqleditor_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.sqlscrapbook_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.datatools.sqltools.tabledataeditor_1.2.0.201701131441.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.debug.core_3.11.0.v20170605-1534.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.debug.ui_3.12.0.v20170605-1534.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.draw2d_3.10.100.201606061308.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.dstore.core_3.4.0.201501311530.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.dstore.extra_2.1.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.core.commands_0.12.100.v20170513-0428.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.core.contexts_1.6.0.v20170322-1144.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.core.di_1.6.100.v20170421-1418.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.core.di.annotations_1.6.0.v20170119-2002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.core.di.extensions_0.15.0.v20170228-1728.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.core.di.extensions.supplier_0.15.0.v20170407-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.core.services_2.1.0.v20170407-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.emf.xpath_0.2.0.v20160630-0728.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.bindings_0.12.1.v20170823-1632.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.css.core_0.12.101.v20170712-1547.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.css.swt_0.13.1.v20170808-1940.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.css.swt.theme_0.11.0.v20170312-2302.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.di_1.2.100.v20170414-1137.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.dialogs_1.1.100.v20170104-1425.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.model.workbench_2.0.1.v20170713-1800.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.services_1.3.0.v20170307-2032.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.widgets_1.2.0.v20160630-0736.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.workbench_1.5.1.v20170815-1446.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.workbench.addons.swt_1.3.1.v20170319-1442.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.workbench.renderers.swt_0.14.101.v20170713-1343.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.workbench.swt_0.14.101.v20170710-1119.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.e4.ui.workbench3_0.14.0.v20160630-0740.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ecf_3.8.0.v20170104-0657.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ecf.filetransfer_5.0.0.v20160817-1024.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ecf.identity_3.8.0.v20161203-2153.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ecf.provider.filetransfer_3.2.300.v20161203-1840.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ecf.provider.filetransfer.httpclient4_1.1.200.v20170314-0133.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ecf.provider.filetransfer.httpclient4.ssl_1.1.0.v20160817-1024.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ecf.provider.filetransfer.ssl_1.0.0.v20160817-1024.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ecf.ssl_1.2.0.v20160817-1024.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.eclemma.core_3.0.0.201706140232.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.eclemma.doc_3.0.0.201706140232.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.eclemma.ui_3.0.0.201706140232.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.egit_4.8.0.201706111038-r.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.egit.core_4.8.0.201706111038-r.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.egit.doc_4.8.0.201706111038-r.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.egit.mylyn.ui_4.8.0.201706111038-r.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.egit.ui_4.8.0.201706111038-r.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf_2.6.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.ant_2.8.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.codegen_2.12.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.codegen.ecore_2.13.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.codegen.ecore.ui_2.13.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.codegen.ui_2.6.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.common_2.13.0.v20170609-0707.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.common.ui_2.12.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.converter_2.8.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.databinding_1.3.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.databinding.edit_1.3.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.ecore_2.13.0.v20170609-0707.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.ecore.change_2.11.0.v20170609-0707.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.ecore.change.edit_2.6.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.ecore.edit_2.9.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.ecore.editor_2.13.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.ecore.xmi_2.13.0.v20170609-0707.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.edit_2.12.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.edit.ui_2.13.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.exporter_2.7.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.importer_2.9.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.importer.ecore_2.8.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.importer.java_2.8.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.importer.rose_2.8.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.mapping_2.9.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.mapping.ecore_2.6.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.mapping.ecore.editor_2.6.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.mapping.ecore2ecore_2.9.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.mapping.ecore2ecore.editor_2.7.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.mapping.ecore2xml_2.9.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.mapping.ecore2xml.ui_2.8.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.emf.mapping.ui_2.7.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.epp.logging.aeri.core_2.0.6.v20170906-1226.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.epp.logging.aeri.ide_2.0.6.v20170906-1226.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.epp.mpc.core_1.6.1.v20170817-1804.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.epp.mpc.core.win32_1.6.1.v20170817-1804.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.epp.mpc.help.ui_1.6.1.v20170817-1804.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.epp.mpc.ui_1.6.1.v20170906-1438.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.epp.package.common_4.7.1.20170914-1200/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.epp.package.jee_4.7.1.20170914-1200/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.app_1.3.400.v20150715-1528.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.bidi_1.1.0.v20160728-1031.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.common_3.9.0.v20170207-1454.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.concurrent_1.1.0.v20130327-1442.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.console_1.1.300.v20170512-2111.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.ds_1.5.0.v20170307-1429.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.event_1.4.0.v20170105-1446.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.frameworkadmin_2.0.300.v20160504-1450.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.frameworkadmin.equinox_1.0.800.v20170524-1345.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.http.jetty_3.4.0.v20170503-2025.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.http.registry_1.1.400.v20150715-1528.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.http.servlet_1.4.0.v20170524-1452.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.jsp.jasper_1.0.500.v20150119-1358.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.jsp.jasper.registry_1.0.300.v20130327-1442.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.launcher_1.4.0.v20161219-1356.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.500.v20170531-1133/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.artifact.repository_1.1.600.v20170906-1259.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.console_1.0.600.v20170511-1106.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.core_2.4.101.v20170906-1259.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.director_2.3.300.v20160504-1450.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.director.app_1.0.500.v20160419-0834.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.directorywatcher_1.1.100.v20150423-1455.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.discovery_1.0.400.v20160504-1450.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.discovery.compatibility_1.0.201.v20170906-1259.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.engine_2.5.0.v20170319-2002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.extensionlocation_1.2.300.v20160419-0834.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.garbagecollector_1.0.300.v20160504-1450.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.jarprocessor_1.0.500.v20160504-1450.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.metadata_2.3.200.v20170511-1106.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.metadata.repository_1.2.401.v20170906-1259.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.operations_2.4.300.v20170511-1106.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.publisher_1.4.200.v20170511-1216.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.publisher.eclipse_1.2.201.v20170906-1259.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.reconciler.dropins_1.1.400.v20160504-1450.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.repository_2.3.301.v20170906-1259.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.repository.tools_2.1.400.v20170511-1216.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.touchpoint.eclipse_2.1.501.v20170906-1259.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.touchpoint.natives_1.2.200.v20170511-1216.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.transport.ecf_1.1.300.v20161004-0244.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.ui_2.5.1.v20170906-1259.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.ui.discovery_1.0.300.v20170418-0708.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.ui.importexport_1.1.301.v20170816-1007.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.ui.sdk_1.0.500.v20170511-1216.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.ui.sdk.scheduler_1.3.100.v20170418-0708.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.updatechecker_1.1.400.v20170106-2125.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.p2.updatesite_1.0.601.v20170906-1259.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.preferences_3.7.0.v20170126-2132.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.registry_3.7.0.v20170222-1344.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.security_1.2.300.v20170505-1235.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.security.ui_1.1.400.v20170505-1235.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.security.win32.x86_64_1.0.100.v20130327-1442.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.simpleconfigurator_1.2.0.v20170110-1705.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.simpleconfigurator.manipulator_2.0.300.v20170515-0721.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.equinox.util_1.0.500.v20130404-1337.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.gef_3.11.0.201606061308.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.help_3.8.1.v20170815-1448.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.help.base_4.2.101.v20170906-1700.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.help.ui_4.1.0.v20170311-0931.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.help.webapp_3.9.1.v20170816-0843.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt_3.13.1.v20170906-1700.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.annotation_2.1.100.v20170511-1408.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.annotation_1.1.100.v20160418-1457.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.apt.core_3.5.0.v20170411-0710.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.apt.pluggable.core_1.2.0.v20170322-1054.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.apt.ui_3.5.0.v20170505-1107.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.compiler.apt_1.3.0.v20170502-0408.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.compiler.tool_1.2.0.v20170502-0408.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.core_3.13.0.v20170516-1929.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.core.manipulation_1.9.0.v20161219-2145.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.debug_3.11.0.v20170510-1451/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.debug.ui_3.8.1.v20170826-0709.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.doc.user_3.13.0.v20170608-0925.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.junit_3.10.0.v20170208-1347.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.junit.core_3.9.0.v20170316-1142.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.junit.runtime_3.4.600.v20160505-0715.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.junit4.runtime_1.1.600.v20160505-0715.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.launching_3.9.0.v20170419-1235.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jdt.ui_3.13.1.v20170822-1011.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jem_2.0.600.v201302011850.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jem.beaninfo_2.0.300.v201302011850.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jem.beaninfo.vm_2.0.300.v201302011850.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jem.beaninfo.vm.common_2.0.300.v201302011850.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jem.proxy_2.0.500.v201504161518.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jem.util_2.1.201.v201707201954.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jem.workbench_2.0.400.v201302011850.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jetty.continuation_9.4.5.v20170502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jetty.http_9.4.5.v20170502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jetty.io_9.4.5.v20170502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jetty.security_9.4.5.v20170502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jetty.server_9.4.5.v20170502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jetty.servlet_9.4.5.v20170502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jetty.util_9.4.5.v20170502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jetty.webapp_9.4.5.v20170502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jetty.xml_9.4.5.v20170502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jface_3.13.1.v20170810-0135.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jface.databinding_1.8.100.v20170503-1507.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jface.text_3.12.0.v20170523-1043.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jgit_4.8.0.201706111038-r.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jgit.archive_4.8.0.201706111038-r.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.common.branding_1.4.0.v201309202144.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.common.core_1.5.0.v201603181811.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.common.eclipselink.branding_1.3.100.v201309202144.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.common.eclipselink.core_1.3.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.common.ui_1.4.200.v201705180510.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.common.utility_2.4.0.v201603181811.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.dbws.eclipselink.branding_1.2.100.v201309202144.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.dbws.eclipselink.core.gen_1.1.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.dbws.eclipselink.ui_1.1.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.doc.user_3.2.100.v201308231650.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jaxb.branding_1.4.0.v201309202144.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jaxb.core_1.4.100.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jaxb.core.schemagen_1.1.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jaxb.eclipselink.branding_1.4.100.v201309202144.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jaxb.eclipselink.core_1.3.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jaxb.eclipselink.core.schemagen_1.2.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jaxb.eclipselink.ui_1.4.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jaxb.ui_1.5.100.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.annotate_1.0.100.v201309261652.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.branding_3.4.0.v201309202144.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.core_3.5.0.v201603181811.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.db_2.2.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.db.ui_2.1.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.eclipselink.branding_3.4.0.v201309202144.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.eclipselink.core_2.4.100.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.eclipselink.core.ddlgen_2.2.200.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.eclipselink.ui_2.4.100.v201603180253.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.gen_2.3.200.v201512212242.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jpt.jpa.ui_3.4.200.v201705180510.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jsch.core_1.3.0.v20160422-1917.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jsch.ui_1.3.0.v20160323-1650.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jsf.branding_3.5.0.v201309172308.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.json_1.0.100.v201612232120.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.common.annotations.controller_1.1.300.v201302011850.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.common.annotations.core_1.1.300.v201302011850.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.common.annotations.ui_1.1.300.v201302011850.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.common.frameworks_1.1.701.v201509021802.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.common.project.facet.core_1.4.500.v201508121553.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.common.project.facet.ui_1.4.510.v201501141810.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.common.ui_1.0.301.v201707201954.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ejb.doc.user_1.1.301.v201105130955.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ejb.ui_1.1.910.v201701262130.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ejb.ui.infopop_1.0.300.v201002231012.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee_1.2.100.v201706292127.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.core_1.3.300.v201706300342.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.doc.user_1.1.400.v201008122207.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.ejb_1.1.900.v201701262105.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.ejb.annotation.model_1.1.400.v201701262105.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.ejb.annotations.emitter_1.1.300.v201701262105.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.ejb.annotations.ui_1.1.300.v201701262105.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.ejb.annotations.xdoclet_1.2.300.v201701262105.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.infopop_1.0.300.v201309091923.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.jca_1.1.900.v201701262104.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.jca.ui_1.1.600.v201701262104.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.navigator.ui_1.1.700.v201701262104.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.ui_1.1.920.v201707202055.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.web_1.1.900.v201701262104.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.webservice_1.1.500.v201701262104.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.webservice.ui_1.1.600.v201701262104.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.j2ee.xdoclet.runtime_1.1.300.v201004280609.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jee_1.0.900.v201706300342.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jee.ejb_1.0.500.v201701262105.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jee.ui_1.0.800.v201701262104.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jee.web_1.0.600.v201701262104.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport_1.4.0.v201309172102.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.common_1.5.101.v201504022146.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.common.runtime_1.4.0.v201309172102.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.common.ui_1.5.100.v201701270025.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.core_1.8.0.v201704192341.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.doc.user_1.5.0.v201309172352.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.facelet.core_1.4.0.v201704192341.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.facelet.ui_1.3.110.v201603071844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.facesconfig_1.5.100.v201701270025.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.facesconfig.ui_1.5.0.v201309172102.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.standard.tagsupport_1.5.0.v201309172102.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsf.ui_1.6.100.v201701270025.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsp.core_1.2.1001.v201707050024.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsp.ui_1.1.1200.v201702270522.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.jsp.ui.infopop_1.0.200.v201707252002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.pagedesigner_1.8.0.v201704192341.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.pagedesigner.jsf.ui_1.5.0.v201309172102.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.pagedesigner.jsp.core_1.5.100.v201603071844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.core_1.2.500.v201603031514.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.generic.core_1.0.900.v201606081655.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.generic.jonas_1.5.500.v201405151744.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.generic.ui_1.0.600.v201707132334.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.preview.adapter_1.1.300.v201606081655.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.tomcat.core_1.1.900.v201705172117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.tomcat.ui_1.1.600.v201609072248.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.ui_1.1.300.v201309182039.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.ui.doc.user_1.0.600.v201309182117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.server.ui.infopop_1.0.500.v201309182117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.servlet.ui_1.1.910.v201701262104.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.servlet.ui.infopop_1.0.500.v201105121947.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.standard.schemas_1.2.201.v201501151629.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws_1.0.800.v201701262139.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.annotations.core_1.2.200.v201311102023.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis.consumption.core_1.0.550.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis.consumption.ui_1.0.900.v201701262139.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis.creation.ui_1.0.900.v201701262139.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis.infopop_1.0.400.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis.ui.doc.user_1.1.200.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis2.consumption.core_1.0.200.v201309242118.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis2.consumption.ui_1.0.200.v201309242118.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis2.core_1.0.300.v201309242118.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis2.creation.core_1.0.200.v201309242118.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis2.creation.ui_1.0.200.v201309242118.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis2.ui_1.0.400.v201309242118.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.axis2.ui.doc.user_1.0.200.v201309242118.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.consumption_1.0.950.v201701262139.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.consumption.infopop_1.0.400.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.consumption.ui_1.1.850.v201701262139.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.consumption.ui.doc.user_1.0.700.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.creation.ejb.ui_1.0.250.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.creation.ui_1.0.950.v201701262139.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.cxf.consumption.core_1.0.400.v201701262158.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.cxf.consumption.ui_1.0.400.v201701262158.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.cxf.core_1.1.300.v201701262158.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.cxf.creation.core_1.0.500.v201701262158.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.cxf.creation.ui_1.0.300.v201403242125.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.cxf.doc.user_1.0.300.v201309232209.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.cxf.ui_1.0.300.v201309232152.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.doc.user_1.0.700.v201612121628.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.infopop_1.0.400.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxb.core_1.0.200.v201309232152.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxrs.core_1.0.700.v201701262139.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxrs.ui_1.0.700.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxws.core_1.0.500.v201701262158.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxws.doc.user_1.0.400.v201309232209.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxws.dom.integration_1.0.300.v201308151836.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxws.dom.runtime_1.0.300.v201308151836.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxws.dom.ui_1.0.100.v201308151836.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxws.ui_1.0.401.v201504291921.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.jaxws.utils_1.0.301.v201504272154.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.uddiregistry_1.0.600.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.jst.ws.ui_1.0.600.v201701262139.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ltk.core.refactoring_3.8.0.v20170105-1156.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ltk.ui.refactoring_3.9.0.v20170412-0825.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.archetype.common_1.8.1.20170728-1531/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.core_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.core.ui_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.discovery_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.editor_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.editor.xml_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.importer_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.jdt_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.jdt.ui_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.launching_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.lifecyclemapping.defaults_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.logback.appender_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.logback.configuration_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.maven.indexer_1.8.1.20170728-1531/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.maven.runtime_1.8.1.20170728-1531/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.maven.runtime.slf4j.simple_1.8.1.20170728-1531/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.model.edit_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.profiles.core_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.profiles.ui_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.refactoring_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.scm_1.8.1.20170728-1531.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.workspace.cli_0.3.1.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.wtp_1.3.3.20170823-1905.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.wtp.jaxrs_1.3.3.20170823-1905.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.wtp.jpa_1.3.3.20170823-1905.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.wtp.jsf_1.3.3.20170823-1905.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.wtp.overlay_1.3.3.20170823-1905.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.m2e.wtp.overlay.ui_1.3.3.20170823-1905.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.bugzilla.core_3.23.1.v20170623-0008.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.bugzilla.ide_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.bugzilla.ui_3.23.1.v20170623-0008.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.core_3.23.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.identity.core_1.15.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.net_3.23.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.notifications.core_1.15.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.notifications.feed_1.15.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.notifications.ui_1.15.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.repositories.core_1.15.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.repositories.ui_1.15.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.screenshots_3.23.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.ui_3.23.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.workbench_3.23.0.v20170503-0014.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.commons.xmlrpc_3.23.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.context.core_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.context.tasks.ui_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.context.ui_3.23.0.v20170414-0629.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.debug.ui_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.discovery.core_3.23.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.discovery.ui_3.23.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.help.ui_3.23.1.v20170623-0008.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.ide.ant_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.ide.ui_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.java.tasks_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.java.ui_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.monitor.core_3.23.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.monitor.ui_3.23.0.v20170411-1844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.resources.ui_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.tasks.bugs_3.23.1.v20170623-0008.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.tasks.core_3.23.1.v20170623-0008.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.tasks.index.core_3.23.1.v20170623-0008.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.tasks.index.ui_3.23.1.v20170623-0008.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.tasks.search_3.23.1.v20170623-0008.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.tasks.ui_3.23.1.v20170623-0008.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.team.ui_3.23.0.v20170411-2108.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.ant_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.asciidoc_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.asciidoc.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.confluence_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.confluence.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.context.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.help.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.html_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.markdown_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.markdown.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.mediawiki_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.mediawiki.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.osgi_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.tasks.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.textile_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.textile.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.tracwiki_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.tracwiki.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.twiki_3.0.6.20170311142502.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.twiki.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.mylyn.wikitext.ui_3.0.6.201703111926.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.nebula.widgets.tablecombo_1.0.0.201707111605.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.base_1.8.0.v20170318-0624.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.base.edit_1.8.0.v20170318-0624.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.extractor.lib_1.3.0.v20161116-0647.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.jreinfo_1.8.0.v20170318-0624.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.jreinfo.ui_1.8.0.v20170327-1117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.jreinfo.win32.x86_64_1.2.0.v20160426-0508.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.p2_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.p2.core_1.8.0.v20170410-0909.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.p2.doc_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.p2.edit_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.p2.ui_1.8.0.v20170327-1117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.predicates_1.8.0.v20170327-1117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.predicates.edit_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.preferences_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.resources_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.resources.edit_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup_1.8.0.v20170408-0745.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup.core_1.8.0.v20170531-0903.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup.doc_1.9.0.v20170706-0615.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup.edit_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup.editor_1.8.0.v20170327-1117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup.p2_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup.p2.edit_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup.sync_1.8.0.v20170530-1735.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup.ui_1.8.0.v20170530-1735.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.setup.ui.questionnaire_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.ui_1.8.0.v20170327-1117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.util_1.8.0.v20170706-0534.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.workingsets_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.workingsets.edit_1.8.0.v20170318-0419.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.oomph.workingsets.editor_1.8.0.v20170327-1117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.osgi_3.12.1.v20170821-1548.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.osgi.compatibility.state_1.1.0.v20170516-1513.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.osgi.services_3.6.0.v20170228-1906.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.osgi.util_3.4.0.v20170111-1608.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde_3.13.1.v20170906-1700.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.api.tools_1.1.101.v20170714-0724.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.api.tools.annotations_1.1.0.v20170118-0848.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.api.tools.ui_1.1.101.v20170810-1621.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.build_3.9.300.v20170515-0912/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.core_3.11.100.v20170517-0724.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.doc.user_3.13.1.v20170830-1120.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.ds.annotations_1.1.0.v20170516-2121.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.ds.core_1.1.100.v20170515-0910.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.ds.lib_1.1.0.v20170303-1624/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.ds.ui_1.1.100.v20170515-0910.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.ds1_2.lib_1.0.0.v20170303-1624/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.genericeditor.extension_1.0.0.v20170315-0955.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.junit.runtime_3.5.0.v20151013-0625.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.launching_3.7.0.v20170322-1119.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.runtime_3.6.0.v20170413-1620.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.ua.core_1.1.0.v20170201-2036.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.ua.ui_1.1.100.v20170515-0910.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.ui_3.10.1.v20170804-0814.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.pde.ui.templates_3.6.100.v20170515-0910.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.persistence.antlr_3.2.0.v201302191141.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.persistence.asm_5.0.1.v201405080102.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.persistence.core_2.6.0.v20140809-296a69f.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.persistence.dbws_2.6.0.v20140809-296a69f.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.persistence.dbws.builder_2.6.0.v20140809-296a69f.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.persistence.jpa_2.6.0.v20140809-296a69f.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.persistence.jpa.jpql_2.6.0.v20140809-296a69f.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.persistence.moxy_2.6.0.v20130815-a4708b6.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.platform_4.7.1.v20170906-1700/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.platform.doc.user_4.7.1.v20170630-0820.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rcp_4.7.1.v20170906-1700.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.apidocs_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.apidocs.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.calls_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.calls.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.chain.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.completion.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.constructors_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.constructors.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.coordinates_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.coordinates.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.injection_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.jayes_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.jayes.io_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.jdt_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.models_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.models.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.mylyn.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.net_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.overrides_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.overrides.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.subwords.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.types.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.utils_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.recommenders.utils.rcp_2.4.10.v20170911-1410.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse_3.5.0.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.connectorservice.dstore_3.1.301.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.connectorservice.local_2.1.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.connectorservice.ssh_2.1.300.201505220524.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.connectorservice.telnet_1.2.300.201505220524.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.core_3.3.100.201603151753.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.doc.user_3.4.100.201403101646.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.dstore.security_3.0.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.efs_2.1.401.201507172212.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.efs.ui_2.1.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.files.ui_3.2.200.201507172213.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.importexport_1.2.300.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.processes.ui_3.0.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.services_3.3.0.201506120731.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.services.dstore_3.3.0.201406041609.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.services.files.ftp_3.0.500.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.services.local_2.2.1.201507180454.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.services.ssh_3.2.100.201403281521.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.services.telnet_2.0.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.shells.ui_3.0.500.201403271554.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.files.core_3.3.1.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.files.dstore_2.1.300.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.files.ftp_2.2.100.201601281414.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.files.local_2.1.300.201403251512.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.files.ssh_2.1.300.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.processes.core_3.1.300.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.processes.dstore_2.1.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.processes.local_2.1.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.processes.shell.linux_1.1.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.shells.core_3.1.300.201403271554.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.shells.dstore_2.1.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.shells.local_2.1.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.shells.ssh_2.1.400.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.subsystems.shells.telnet_1.2.300.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.ui_3.3.400.201704241037.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.rse.useractions_1.1.500.201403100950.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.search_3.11.100.v20170515-1603.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.swt_3.106.1.v20170829-0553.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.swt.win32.win32.x86_64_3.106.1.v20170829-0553.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.team.core_3.8.100.v20170516-0820.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.team.genericeditor.diff.extension_1.0.1.v20170809-1356.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.team.ui_3.8.1.v20170515-1133.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.text_3.6.100.v20170203-0814.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.tm.terminal.connector.local_4.2.0.201609191434.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.tm.terminal.connector.process_4.2.0.201609191434.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.tm.terminal.connector.ssh_4.2.0.201609191434.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.tm.terminal.connector.telnet_4.2.0.201609191434.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.tm.terminal.control_4.3.0.201706130821.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.tm.terminal.view.core_4.2.0.201609191434.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.tm.terminal.view.ui_4.3.0.201706130844.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.tools.layout.spy_1.0.0.v20170428-1608.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui_3.109.0.v20170411-1742.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.browser_3.6.100.v20170418-1342.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.cheatsheets_3.5.100.v20170515-0748.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.console_3.7.1.v20170728-0806.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.editors_3.11.0.v20170202-1823.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.externaltools_3.4.0.v20161212-0515.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.forms_3.7.101.v20170815-1446.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.genericeditor_1.0.1.v20170822-2211.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.ide_3.13.1.v20170822-1526.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.ide.application_1.2.0.v20170512-1452.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.intro_3.5.100.v20170418-0710.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.intro.quicklinks_1.0.100.v20170515-0756.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.intro.universal_3.3.100.v20170515-1335.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.monitoring_1.1.100.v20170131-1736.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.navigator_3.7.0.v20170418-1342.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.navigator.resources_3.6.1.v20170823-1443.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.net_1.3.100.v20170516-0820.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.themes_1.2.1.v20170809-1435/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.trace_1.1.0.v20170201-2036.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.views_3.9.0.v20170226-1833.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.views.log_1.2.100.v20170515-1458.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.views.properties.tabbed_3.8.1.v20170713-0803.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.win32_3.3.0.v20160505-1310.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.workbench_3.110.1.v20170704-1208.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.ui.workbench.texteditor_3.10.100.v20170426-2021.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.update.configurator_3.3.400.v20160506-0750.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.userstorage_1.1.0.v20170328-0205.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.userstorage.oauth_1.0.0.v20170526-1605.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.userstorage.ui_1.0.2.v20170526-1605.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.command.env_1.0.500.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.command.env.core_1.0.300.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.command.env.doc.user_1.5.400.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.command.env.infopop_1.0.200.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.command.env.ui_1.1.200.v201503231435.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.core_1.2.0.v200908251833.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.emf_1.2.500.v201701191735.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.emfworkbench.integration_1.2.101.v201107081800.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.environment_1.0.400.v200912181831.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.frameworks_1.2.201.v201707201954.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.frameworks.ui_1.2.400.v201504292002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.infopop_1.0.300.v201309101952.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.modulecore_1.3.0.v201705041406.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.modulecore.ui_1.0.301.v201707201954.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.project.facet.core_1.4.300.v201111030423.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.project.facet.ui_1.4.601.v201707201954.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.snippets_1.2.300.v201705162046.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.ui_1.1.500.v200911182011.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.common.uriresolver_1.2.300.v201702270556.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.css.core_1.1.1000.v201704250120.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.css.ui_1.0.1100.v201704250105.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.doc.user_1.2.0.v201707252002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.dtd.core_1.1.700.v201211012112.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.dtd.ui_1.0.801.v201308100602.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.dtd.ui.infopop_1.0.400.v201707252002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.dtdeditor.doc.user_1.0.700.v201208081537.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.html.core_1.2.101.v201707042220.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.html.ui_1.0.1200.v201608060428.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.html.ui.infopop_1.0.201.v201707252002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.internet.cache_1.0.800.v201702270716.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.internet.monitor.core_1.0.600.v201309182039.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.internet.monitor.ui_1.0.700.v201309182039.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.chromium_0.5.200.v201610211901.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.chromium.debug_0.4.0.v201605131737.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.chromium.debug.core_0.5.300.v201705091354.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.chromium.debug.js_0.1.200.v201610211901.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.chromium.debug.jsdtbridge_0.5.200.v201610211901.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.chromium.debug.ui_0.6.200.v201701261810.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.chromium.wip.eclipse_0.5.200.v201610212001.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.chromium.wipbackend.dev_0.5.200.v201610212001.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.chromium.wipbackend.protocol_1_0_0.5.200.v201610212001.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.core_2.0.300.v201703171536.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.debug.core_3.2.200.v201610211901.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.debug.crossfire_1.0.500.v201505071819.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.debug.rhino_1.0.500.v201605251607.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.debug.rhino.debugger_1.0.600.v201604292217.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.debug.rhino.ui_1.0.500.v201604292217.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.debug.transport_1.0.300.v201502261613.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.debug.ui_1.0.600.v201605311817.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.doc_2.0.200.v201610220243.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.js.bower_1.0.200.v201610220243.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.js.cli_1.0.0.v201605192332.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.js.common_1.0.200.v201610211901.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.js.grunt_1.0.200.v201610211901.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.js.gulp_1.0.200.v201610211901.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.js.node_1.1.100.v201705091354.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.js.node.common_1.0.0.v201605131737.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.js.npm_1.0.200.v201610211901.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.manipulation_1.0.601.v201602241911.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.support.firefox_1.0.501.v201602241911.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.support.ie_1.0.601.v201602241911.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.ui_2.0.300.v201704191905.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.web.core_1.0.901.v201707142218.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.web.support.jsp_1.0.600.v201307151913.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.jsdt.web.ui_1.0.801.v201602241914.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.bower.core_1.0.0.v201605150457.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.bower.ui_1.0.0.v201605201503.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.core_1.0.100.v201707252002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.eslint.core_1.0.0.v201605150457.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.eslint.ui_1.0.0.v201605201503.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.jshint.core_1.0.0.v201605150457.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.jshint.ui_1.0.0.v201605201503.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.npm.core_1.0.0.v201605150457.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.npm.ui_1.0.0.v201605201503.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.schemaprocessor_1.0.200.v201704192002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.json.ui_1.0.100.v201612232120.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.server.core_1.10.0.v201705172051.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.server.discovery_1.3.100.v201705102053.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.server.http.core_1.0.300.v201606081655.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.server.http.ui_1.0.400.v201309182039.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.server.preview_1.1.500.v201704201544.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.server.preview.adapter_1.1.300.v201708030026.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.server.ui_1.5.400.v201705172051.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.server.ui.doc.user_1.1.600.v201309182117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.server.ui.infopop_1.1.200.v201309182117.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.sse.core_1.1.1001.v201707042225.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.sse.doc.user_1.1.100.v201208081537.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.sse.ui_1.3.600.v201707042340.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.sse.ui.infopop_1.0.300.v201707252002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.standard.schemas_1.0.800.v201706011851.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.validation_1.2.701.v201707142105.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.validation.infopop_1.0.300.v201309101952.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.validation.ui_1.2.501.v201707142105.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.web_1.1.800.v201312041437.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.web.ui_1.1.601.v201602221748.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.web.ui.infopop_1.0.300.v200805140206.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.webtools.doc.user_1.0.500.v201208081537.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.ws_1.1.400.v201503231435.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.ws.explorer_1.0.900.v201612121628.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.ws.infopop_1.0.400.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.ws.parser_1.0.600.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.ws.service.policy_1.0.450.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.ws.service.policy.ui_1.0.500.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.ws.ui_1.1.300.v201503231435.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.wsdl_1.2.400.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.wsdl.ui_1.2.800.v201510282151.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.wsdl.ui.doc.user_1.0.850.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.wsdl.validation_1.1.700.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.wsi_1.0.600.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.wsi.ui_1.0.600.v201505131719.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.wsi.ui.doc.user_1.0.750.v201309242123.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xml.core_1.1.1100.v201705012045.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xml.ui_1.1.800.v201704102213.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xml.ui.infopop_1.0.400.v201707252002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xml.xpath.core_1.3.1.v201509231858.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xml.xpath.ui_1.1.102.v201509231858.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xml.xpath2_1.1.0.v201309251557.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xml.xpath2.processor_2.1.101.v201409111854.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xml.xpath2.processor.doc.user_2.0.0.v201209212251.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xml.xpath2.wtptypes_2.0.0.v201208081543.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xmleditor.doc.user_1.0.700.v201707252002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsd.core_1.1.900.v201401141857.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsd.ui_1.2.600.v201511240159.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsdeditor.doc.user_1.0.800.v201707252002.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl_1.2.0.v201309251559.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.core_1.1.301.v201405151730.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.debug.ui_1.0.302.v201304240928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.doc_1.0.100.v201309251559.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.exslt.core_1.0.0.v201005240422.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.exslt.ui_1.0.0.v201006012004.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.jaxp.debug_1.0.300.v201304102131.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.jaxp.debug.ui_1.0.200.v201103081755.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.jaxp.launching_1.0.300.v201304102131.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.launching_1.1.0.v201304240928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.saxon_1.0.200.v201103081755.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.ui_1.1.301.v201304222136.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wst.xsl.xalan_1.0.100.v201208081544.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wtp.epp.package.capabilities_1.3.0.v201005102000.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wtp.epp.package.jee.intro_1.3.0.v201006142040.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wtp.javascript.capabilities_1.0.100.v201005102000.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wtp.jee.capabilities_1.0.100.v201005102000.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wtp.web.capabilities_1.0.100.v201005102000.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.wtp.xml.capabilities_1.0.100.v201005102000.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.xsd_2.13.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.eclipse.xsd.edit_2.8.0.v20170609-0928.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.gradle.toolingapi_3.5.0.v20170801075239.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.hamcrest.core_1.3.0.v201303031735.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.jacoco.agent_0.7.9.v20170208-1730.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.jacoco.core_0.7.9.v20170208-1730.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.jacoco.report_0.7.9.v20170208-1730.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.jdom_1.1.1.v201101151400.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.jsoup_1.7.2.v201411291515.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.junit_4.12.0.v201504281640/ +file:/C:/Users/jinyu/.p2/pool/plugins/org.mozilla.javascript_1.7.5.v201504281450.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.objectweb.asm_5.2.0.v20170126-0011.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.objectweb.asm_5.0.1.v201404251740.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.objectweb.asm.commons_5.2.0.v20170126-0011.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.objectweb.asm.tree_5.2.0.v20170126-0011.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.objectweb.asm.tree_5.0.1.v201404251740.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.sat4j.core_2.3.5.v201308161310.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.sat4j.pb_2.3.5.v201404071733.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.slf4j.api_1.7.2.v20121108-1250.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.slf4j.impl.log4j12_1.7.2.v20131105-2200.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.sonatype.m2e.mavenarchiver_0.17.2.201606141937-signed-20160830073346.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.tukaani.xz_1.5.0.v20170111-1717.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.uddi4j_2.0.5.v200805270300.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.w3c.css.sac_1.3.1.v200903091627.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.w3c.dom.events_3.0.0.draft20060413_v201105210656.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.w3c.dom.smil_1.0.1.v200903091627.jar +file:/C:/Users/jinyu/.p2/pool/plugins/org.w3c.dom.svg_1.1.0.v201011041433.jar diff --git a/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml index 690670e..83e3255 100644 --- a/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml +++ b/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml @@ -1,8 +1,34 @@
+
+ + + + + +
+
+ + + + + + + + + +
+
+ + +
+
+ + +
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench.texteditor/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.workbench.texteditor/dialog_settings.xml new file mode 100644 index 0000000..aef57a9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ui.workbench.texteditor/dialog_settings.xml @@ -0,0 +1,21 @@ + +
+
+ + + + + + + + + +
+
+ + + + + +
+
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml index 70080ea..5593325 100644 --- a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml +++ b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml @@ -1,9 +1,5 @@
-
- - -
@@ -16,23 +12,10 @@
-
-
- - + - - - -
-
- - - - -
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml index 0148db2..e0ae5d3 100644 --- a/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml +++ b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml @@ -1,4 +1,5 @@ + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.wst.jsdt.core/externalLibsTimeStamps b/.metadata/.plugins/org.eclipse.wst.jsdt.core/externalLibsTimeStamps index af947771cd85321fd5f7c598e59f6a0e9eeac0b0..960f66f36b00e545b9d3800560f4c15d5868104b 100644 GIT binary patch delta 29 jcmaFN{Fs@Afq{W_Vs0E`{KR~(i2-tqfk1k)7~@$0e&`79 delta 24 gcmaFN{Fs@Afq{W_Vqz9!@WeA-69a@co|a$)09$_twEzGB diff --git a/.metadata/version.ini b/.metadata/version.ini index d0ebdb2..6b6ec34 100644 --- a/.metadata/version.ini +++ b/.metadata/version.ini @@ -1,3 +1,3 @@ -#Mon Aug 28 00:49:46 CST 2017 +#Tue Oct 10 23:09:53 CST 2017 org.eclipse.core.runtime=2 -org.eclipse.platform=4.7.0.v20170612-0950 +org.eclipse.platform=4.7.1.v20170906-1700 diff --git a/.recommenders/caches/identified-project-coordinates.json b/.recommenders/caches/identified-project-coordinates.json index 27340ec..cf39ea6 100644 --- a/.recommenders/caches/identified-project-coordinates.json +++ b/.recommenders/caches/identified-project-coordinates.json @@ -1 +1 @@ -[[{"location":"D:\\javapath\\jre1.8.0_111","type":"JRE","hints":{"EXECUTION_ENVIRONMENT":"JavaSE-1.8"}},"jre:jre:1.8.0"],[{"location":"D:\\jinyu\\udt-java\\judt","type":"PROJECT","hints":{"PROJECT_NAME":"judt"}},"ABSENT"]] \ No newline at end of file +[[{"location":"D:\\javapath\\jre1.8.0_144","type":"JRE","hints":{"EXECUTION_ENVIRONMENT":"JavaSE-1.8"}},"jre:jre:1.8.0"]] \ No newline at end of file diff --git a/.recommenders/caches/manual-mappings.json b/.recommenders/caches/manual-mappings.json index 9e26dfeeb6e641a33dae4961196235bdb965b21b..09f370e38f498a462e1ca0faa724559b6630c04f 100644 GIT binary patch literal 2 JcmZQz0000200961 literal 2 Jcmb=f1ponc0Qmp_ diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fdt b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fdt new file mode 100644 index 0000000000000000000000000000000000000000..ba10aebf34fd60bd0cf5b583a3cd7a26265bf602 GIT binary patch literal 5021699 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

_$#snndIBY4s6;l|yj)3YboCW=un&L|C zmELNLhGJKyyV0m1_8JM!>N-urv@9==FH8TyWlm*FMWFLh=!TBhU%w=G@YMb`t&J7vTq4zoWj_=-gi%0 zzsVpTnCP3X&l9rmv%2j;$HOZF+NLG_*gJ?n2=xlT zE*XY9hh;1tN@uA6QS~Cg!>6ne(0(rhJe1B-0mJ$b2_8^rsRUUU_8D}d!%nxKLqMw_ z?xY)riG>UfbBbCVlu_zC3ZusnHKUS<0%vuDpvW$}2Wu6IGY(Y_&1Zy8_TueXN9wL)qoVsr>51i#g(s^Q2aVZ!DhZIV< z3adKArQhR$pw?*-7?!_;1S^xs+Tbw#EAxq_4{>9SGOw3;y~dx9Czpe9DaYl}2e69T zR(kM!B8ytf{9Ck>3fwJfJ!nbmQaNepwwedWtV)bBztg#f zYX>(SZsI+;JdZS2Lrz`OP8pl1eCxD2hcI^;{j@OIl-A|+X<@RNL>Ssj!EX<}w0-o3 z;&rS`YTrQs-o@l@v%IMF74$imNZjH9&c`}~610R-_IKyXYg}obXwN^lW>Dh_b1^OD zpIa+w{-P8Q$XY?e2DdBgvqN&L>QjQI73Fz)*FM{{Y1XbL@kLPXySkrfbd26AN#W~j z${J85xKCi0uPAj)1+S>XM?ozw>O8~v6;tke?`oQf_FSvS9&gst`T0+K!&#f#Gp@jVQypz{hK6VVk-=5!}EaU4)Y@FAT zVFHhu3`n9$&w&EGOskw?@)7XzFzLuu!v^qpf2Te@;U1Uj^gH#;)5l)(=~0EWl1Eh@ z`a`GNbUWKk7-%dVz?W@9mS~n`b;5&_VukIK7>8sJT8IR_k`hiG*k|RIwB62bXsQd3 zgXEM!8Wk|@HXd84xLt`{2HoA>R}ar$BrVn@v)VO{k-_sq?g3*%Nn%o*^mUq)Oep4E zN;+Z@P{k}Q(>6*1W>=A|nar|%@;#lhYH02$$91f(-rdXg{sE2wwY!GTFfE>-scoyL zhN?N@bsqA7jlbD|+It8P$ul$T6d|dWW)}xpR22}-B~?q#EKG@}bdGoRwq5QLf1?rm zYX|2ZRf1MbsCv{ns#HDi{0ltsU#W2oxL7%^8faPJ?=q=^33+EFbS-5|@>yC$X`Z8^ zvI3IU$mf#VE!lg@`Hz;2%RS{7R8X$HEl|CuZx%$Yk7xUp@f{jsQ!|Zbe->2J~IA!oOUxYM43lq>0Pd7=&1-L01&wBm&E>K>ffYmKm6G!na;+-*_;MHfq$j35u?xmbc|a`CZvP}9W{ zW;bmQbGulC=y5v;t;i3RjrvB0+DO`FqmGb)48a8q8wzsNeMqGa!jFby3AAa*6$QvX z=4?*7S`!4stA0=Ij#-s5E#BifSuw5;%T{gDU7E?^_bp|mRHJ~pQdXU{ZrB56ld>

v7n7jo4Oqr4dc6D;2om=Y%=^ol17XM=YmQNEW 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%0D$!Y8Po|&MJv9aW23Oi?IQar*v@#KuGrDN_ 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ℑ0W^dUV-?P= z+ov#JMBTji-+n$h3-XmN&;EL*b77XhhUq2?>f*2I>89wbGP-ut6pRFV0xK1hb;D0V zIV+hq6bEpvDji}vd%>cHkJA?eycF~o9D3?t{X*AqB1_9BQm=Gze%MN!auDwin@3Sz z?Q`MbOL0|BvnZj+!4e#bE0y2)VHc-Zn5{PV>bZ|t*c1o2JjJ@KXMb~&7v_Y8 z^mI~$L-xc_OUc$EO4Zh&*qWG4)|;uBVilm90!`x2h$$sR>w3v((HC#m_jmotys(}IqK;5d#zh1xaj1!seI7{X^ zsMb6*X}oNp5FU}49v&XPe4i`L;0g%}F``%?+s(ufl0lk3<)R|i#alGG(Ls`?Z~)^HNDkcHb(}ICjCw)LXM0ZoK~;B zOP-JkN2OJOzWWjgzNz;4;p?aSFPxav(EZ%KP%=2_D{-MKoYsc6wyK9}F5A>FRW%Oy zo2%$1p(wYcqZNSFoS?Oeb#Aj92d25X_*c^-_LPMN74~-seVdx(Iv4P~a}^kPczgs8 zQ^ackFf_|xSEg{Cve%;J=L%&n0U>Mqj20^HQ}_|QhW~l`P`j4E8}>7pUcX&`tU^1x z{$P|AGD!iA`9B?7%2Mf~X8um~BZT`Ls_FIH_1H^SK6>JJy20`zgb&-+-(r5md+~P` zF0u+NWfxBBx7YSzz^z$51NK9u?ny{L`A&th7(Mm$*!C=HndL8cP4>S$W0=$k^&JS(9+$RWgQfGdD$-Gzq? z_25LD>GwZ0armZkj+w6gV*}+Q%D_vVYCSekoz<%N;Mhp{O#aMWI&eI6RYPY8U+w2V zKnH-DCUn=mVuD;rqdl-QQbMk$1*fyeHDsAm+8HixuY1rr+Zj^18}YGASMV|zyWKj=6TX0p?aZg;L(mK z(N8E-YMQR+n%EMJAhBG>L?0BjQnyRAf!><68utZJcW+G$bmMFZ<5_9|#AZv7UGB9= zooKTqC?l;h0kcKOzTc{{ik9tWpm_mT_658M0>!KE4~=|UN5SnjYXR~bIhm;E#!pI@ z5>jw)xZlB`1$Zs=CF@rHm-(;*7mg8Z0%r3T6ZWQn8KJ7`;M$#OeCeK_NPOPEQMDpa z_t43WcF47EN@IDPQshven^384+6+uIiZI!et?MZ#ZJp5b)%O%TD9=|CpnGSy)Nqtb z*XN#g&;ZGa8qCL2q=`m~FmtOuMVM?55q7HsRHq0NH5Fk7K=MRk0f0@Pug`C~)RLc9 zFEAmz{_>?6l|r-&eb3q+U;&y->U!77tR z(|UXn-hz21bwe^cZ@7FNzfF`upEq2-hYU9yweyBMwe_nv{4(>$d&Dq9u`+Kw%lC+B z7>R!~{Wt-bM9wfMbwHsbHlVSR!XG*O9N%CZTo=(&v?I!TVgq?ZcWA*4qm95+gvPkz z+T6zLwoc<5TpZW6qk1>?$u?=n@MkBjGZ;!)?DfTe{J2*TbklGBj~DIxgD-Wm^!yhx zv87i(;EjwXNA-d2YH}MwFZ8W$dAzBdK%?NirtqEWUkZV7eStawd8r1Nu-s%7tzjLA zh2&dthJQW%p3LAwEl%Q{F26W3{q~FrRZPm;n>pBrVs3S2Va8ywGUA+EpE5QiIaNvh zjCn`j?&_3z$MoaBo_>b|cY|#yWZ*Upn1x-iD_f*u7~7*Y5y%Zh?h)}vw1Q|ezH zgV6a^9Y;`Bq6I2;%Iv1@a?fN2r1Okb2P@+%O)gZw#QO~^k2-y0yZ+?y@o8v}l*=l+ zqE8z*!JB-Y0+CP-Eq+Vt>3RMgyNfZl0#7hp-C#>cBmp@H2?3Q&AfFPQanwc zW(ht<1xq^AQNTS{@fv6%D*FLX*l^SU2%hKU?^UMDPd({7c{h!Tzn!|+U{t+d@R3+w z!OKxsf^$|n+4sLkP}8mT;FEmUu~PZX>booXoxlpmgJPD1>j6@Z(v*V^XNUV!&E<-A zs4U4TM5i+rT96J1HPt;}WSZON@ilA>T<9E9m*simN3&)w%kzdi9r77}6DgQCezajG zQZR4$XiE*1>%8HkxdOyS1sEx^Ri}b4y8YU=P+5MuhZXLZV48r%au*;%{%fdTs*Lbr z0T~voZ~)l!&|Ky{MW#(k%lc+RorOB`b_h1L-*c9t4G-R&s!^dc1qfaF?_ang+U`Zx zz9BRk=gvz_K$6dh-h+M(qG-%DEiL1k{%xp>K&NSe9wMvG(*I<7T8lub%I#h*b*=1< z8AoL$ism0W`T#Wu_5 z01UFB!?0=Gt=RG96|lMhYLvw^KvTY1ftdo<6NKlqR#Ij32RnqBE|1Uq=6t6PYN_b2 zRΜF@i`>zxZ$|E?g7kM1dL#q7s_i>99#+VusKVlzj&;O?FI_ZiOJPa~(rjF4i9<|&n&1f)VA>oaShhr!i zW{#IP?>!_%DKT@ryh#~vC>>^wSANfl3-C8Dyj=AuAuRc#NuK04(sHaY5ptiFiYPT) zLqh-}!kYLQaoKnSWKxzwbL*Uks_1DCX$cT0wxah^O|o&;Lc+&{9bpw+>e7|j5{B0) zB22z=wg}M(k#Kj$A|8JuB23D2_98^BM1o;{S|Xtx*1+kY0;&5`g!f;*ewXdN_GXu6 z#V)Uj!oz?b6%gBSAg{r4>>yo*gEDfBWKC0Xb^i6#?2d^_C-Fvy29Hed^gup=Pnzf~ z`f)z5cVR%dne)Er$Uk+k@qiIQyLHkeaB=a=YQtFqnh8WQ z2Dp4Tng8PLZ@`*aMK?44TE4CP_4SOu7V98?eW}@;cdlfxiSp-H^MpSS3&%H5C(<#d zOvf)vBG6k9o}72h>CrWg?FU%F7NXG(nv1f=!KB}zjMf#!z>o&IFo{b2hN;BoKp<8AK+qLF6?RO0JS0PrU`eJ?kp^7};7;L%c!lrcs)~ z51KQ7a2CAhrdl@^2ndOzrPVv|00ATad*{pbS8sDe{(_3hf)N?@blhp&W4$L zw*A)aOZ6>j-8X!JREajVlE`IuP>$jHf$4?b(;t!r`YCZ3N>J_f%EF2nhH}86|bv&;dxxT+}th zz5aOm3MT?hedxSJ1XC+9uxot}o-cxT;p6dFXNd4s^LP5vGk+EC>-%Ngp0NxcXuCXT z89q6JW~dwaTcgh|e#V0hx#Pix4J2}48B)HHxn}wz?fMMF!?i=6CFVwB-I~6;EZ_7s z3i0cyLTHJm!05>I-UN9+!xR|J8|!U~DXE$F7d~-K)?!UVRo0T(qAN5``b}Q1DU$E| zv?DeJO)mZ^adYKjZ|ev4OmVHdWDjNJ_ehW{vplxnb*k<5RDsj2r~n2}6*$?Sw;%S* zA&~xIOZ0~C>cf`k?Fvq_+Nis{?)JX#AG?=N-8SxY zG$~qG<_X}~q}HG_HzaG!LFe}<({O(rU4pYT!)KEVoT0#&HCzmx{_^n47xgveH>=mLwI?MH*$Fq^rBCVWD6imh$C+Enx zL8E1$(XbfmZI_k3l7t6KA*X-fBUE*^z?t8^)T2*3;0tK>cTqojr)f>FF8DA{kZEdMW-UXjfGM<@EkU_! zD)}{Agq*8ljZBry5((jgb@Cd-4Mm7ShU5)%Sd|1j#>Jpsq zb{)h11OPbMQ1(C!1~bWqZVd_t8)R*pS@+2{SUC$8r9ZQQlvyZeJU0wh&O$j#X%ytZ zLP4YI-07_6LOH{h_Bwdxg1jc;i>OYEC5TbZL;dtpJ^$pRcp+fqOa>inMMArLLd2i? z?R8y(0a);V;0OR>z5z#~#n+~iLbbC^=C|T+F8;&xoSppTQ2;b6YBaarS@~GWQw3Cg z(r2$(spN+*I`~H)zi6*+*B|^1dDC7pXPjz7-4*5t-M4K88p!>Z*5LraW9Az5hLT}j zFXHq#1HC3A?Vf=T44h58$y)jm;A;fv2IjV|uU%@xwfh%S?G*p!d-eGIfZ;tno#{+H zXW`n4Uh0>9uHcF8UFl}pb0v@a<@Un`hdj`~H=jp)Kh7_n_qj~O84p{9oZYv6e}fCZ zUA_MGgZ%Rf4SeX_?-d{;_6Vih0J6)4wOV&;C}BGstTZbrP%qL1N`wsse+|@)1^l3j z3G(JLzt2LQ>xS_^>qwm-xdZjxMqao5NbI)ZDRH!)md5qF=$-t^fWbs5>x>u23;owr&Mv# z2}>2m&*yJTHQUD%h_k34Vmbt$2SK#DK)yEtDh@ZAS?O<((k~Y3`x{_-GJQ< zsxM&k?S=+iung*ClXlb^5xj6f^p#CV?GkL7z-+bet|8k~Hjp-{JuzFtV4Z!MSjB~A zi;!>Zlf5TP2pvDCNf3RNHJBjX?57wm7+!?F2uv={1MjqJ+?ZOr$saiP_2>KUTlew` zF<2)&b)q&B3&p#J9u6E*7%k#F0o)zb3j&*If+=3ZY*hAjmt{nRxzedxmLpT#?1kPw zZNRdwc`&i2pMcNnz9A$096uYS9L zXt#Tqr76hEDJcH)>8tf^_ExlMahbcI@K|2qRa@5*Ayb_{M@Xo1_)GK9O278J1Tg`V z4Q#q?mORfy`%UA|5-GeDZ;l9vD33ba>eO?E-;Q^^mnWLWzK|@ve|u7l2`+WMUc*&S zhjdhuQ3bFAWUe(Ky@o{4ChCg zJd-aq8$)=$lU6%?dRgx6M=n>kh(G#2_T_p{fZ&JnSqTIgcm(1q11s?0tPTI$sg}1) z!#NI2Mwde)2brJak4;=g32R*U?y8lRln9qOz=$N{6lg!w?U8P9rk1Qr8z}6q!UMs@ zSD)DZ?4147S08lb#vG}8R>FfvT}(%en}zdeRiEW+Iys@lNor8s{`;x6Bj!@?m|YXO zr470w*Ox0D{ncR9PMZyLPmb3gwZ^^N{nB z4;1@q!Y*nlRi-LqhXxUiM3<=#8k~_CEFo@1$g7ZhtwhS9r%Re$>2Y= zUmK6Shc1Uq3aTWOH@J)a?~zt zL-qIJ#1BL?s-|w<`0*4~Zh(i#sEosrDk49;dsk@)iIk zf+El$Bqf>XtVvo&m;eqg{%ArkuKI>D%`~%Z*wp4M!#fG#rmi|_=L#6VgXxEzD}XQI zU!~#eohx9n9Zg^ITnVEp8fLz^0^AbD9j)Hu(POuMdHP1xmG=b(NdAtN)^$WxcfqZU zxLH(#gqv+PRRTHhJCnMpEM1GQDZf5rEn+}qEx1QI#=fVd7;s;?O*m8P{iOr}*l{4efPYI%8pCK4 zBe`0xfxTTfHQ-E?jptNiwJrXXIgf{m;;C2zf3vTicseB5a__tt@S52oWE=a4vW@}G zc^#vwi3n39HG2`FAR@trvgR&A6jdac3a8m?5XJB>LX)Tq?u2~(soN{ReR%rh;^|Kh zq4PtkWYLYH&ft-0V#;`rE!|IP493v6Cacm{mCbq_dnm1QM| zp~AoLi|{$mBNN_S{O9TGKmP&33zA#r)sGM_S}Ef1F8<5MuYPiTUH&NfA+h@d-oDr# zf5-nZ;>W{Xg>*i<(^g$shTjagVON~)8b(0ygeiWV!66C8N(mBI0vA-a0k|E+Hu$MY zebE|9yy$ODzpaS6zDVBvZpVa92S>wmGk?%%F>mJ&lK1URTsn7ogPZ1!^OA>p9@3>; zmGqf^pn&%|ftmb;I};_JuTO(-<@96d&@br9jp_nGahQ3lz5x3$r_i$pmJ)y|GHz8% zGpB<}`Sa<+`5M=i5pKgQ3zlUqhXNQsR8nh}u)P)goRWd_UMgtfPa8PzrIM!m^4w<| zccAhvJ`v^Eg?!|GABvecUGE1vuheynxGf2-Yvu4q0hp_SJ6h*ZDmWgj8g=O6f|MC) z+0No7zL#q9n+ui`KEB@)DxbJe4lmm85|aU5C}*-qO~Q4dpwU7Y%FpF;ykAO~RegAO z*P&xW*+Tz2Vdr~&#xzTq!(X?3PbMiIpgCZa0V=lw?zD{i8V0vDP=i&1836bcZRmb= z@ekDAA7(R>&BtG`r10_mp{^apLq3Vi>b=qlRlNlA!Qm1SCn?a6gjfL%Z{w_ps1mCR z`Vigk;ugqPhzZGZnYP5O?=+QbT*cYT(NAS=SBs>eKVicwtG`rAh|>Ho)6cm`it>)m z6BFWPXFXFe^FJs*>GzT06_Xlvdd~60|K{X}>5Wp? zf;V03_V!5e(#zxhm+HZF5>l%qmLUn?+7;Mh5ZV(H@2RP9Vb!#!UZ0{jI)0ieDycvP z?SWD^6&8Ol*90_=uOn<6pXXL-?s>xpE#2nHRZ#h*dwhD+ZtCzWso~4jH>`mGHKd?{y125qmh{ zqOCxJq)|L-`vzcengsI=+_p7pvdO`->M93cMEK#KOtrz!8LE({@=crI;^l?SvOPPM zF+EgiGtIv?+bA4`R6~to98uU>@nE?l-@rGhKoo3Zm&v4L5dx|{E2$j8HBgT_t%|Y} z-03FgMQhvc2w$6VrHPCdi;~SD@yg2&Sd_;BzCM3Zq2fw$P%VBu**)@jx96|Phlkln zO0^DMf4+6pThU2Vy*|@O^VwTer(4dZ_V`{947CLihEdxU2_)@se>X)|NMA$S_31h< zsnPrM=`QjUu8i;nH%>EBE{da};lMn(ZJVY_=Q4()Bb5gQ*(9sdwvMPh%mF)#vVvL| z*C4dv#vM0c5&%D5*hu!I58unZ(H$jAdgr$*vvxvN0-Y*wV&zc}RZt=k;#K?9ykhp= z2zma+C(4NQ4dvb6a7lIib0Pl&=Ciw=)|5%C3pzj2b=6R<7LfvKNdExr3Y~bBBYrYq4BU1QxGhmp zsFF2Rm2hh>3wpx}$V`$BR~-s=A~sxDD$s#zLnjl2U21lh{gZCb-EddSrY8CDIC)6# zfi4^7J!)zFsn&==Ij;`ah;G<+uw6Aa8qLeOmnlu-*$r#J>&a zh6C1X+j_m`>gD)7V@R&(lZJM_rhKey$~5X|_KP7jp$9@;Hno%aZi+iy`+3SDx4Ph8 z*X74a4CxTnIC<(CWuMEZG3Vx~0!P(a3{Uv(J8YxV{v|F3*4ry^jDsjQt^V5lmRtU- zJ5;AyI{7^ZH2k{{522n4!{qdk+P9djdsD89tl|<3+)E6sBW0HffNd#_I8<8I)W!YT zQNcIb%brX=V^QHO+HN2-h7k!8|K& zShcP@h%=z&>Y!Vx%96qoSaxAvg}5#0`vhb#PF%I;j!bc*N%8_%CR zinVe&da>B?AiDhE#d@gVYu#Ub?qUOQ+Q+>D+1>JDZ$Eae!P(G2TCdMP-GBMMGf(6H z2~XlnJ9u!vuyG#)_G(1J#%)ctagAF=4a7JKfZ+_GqNd_s-)K;WGi1tl7n#=|CR4lue-BV7Drc;7@Hj>2?ME)u z-|NXFt84GE#s#WYzHq6(|M~vy7g|IfM`P-uWR3wd+7KG+3mB?fYV&YbP*dvmYcekY zw*teLaG+4xX^d%@*ac$WPjP$kucyaM_-keI!f$uW*dD&#zr6lHk>Nc5xK)M|UG1Xq zh>IV5xJ7x#=!2Fyx<*`N{$l!pfB{k~FAUZ@(4Lxa?kEVg^UIr5&-u^Q!`IG*_U`-prh2<4+#r|VmE#uMUQ~Gn*n+yrn%sGg zu(9?alt5#*shc8h+cogv?mw6Z(n`O&P(7yG%glmlFEtCxAzy!iRIwP7jdOKTPnG;5 zXOT0`@6I1K$+%yyf9R8Vb9nb-KZ>8__J=--KP(7vM$=Efn=d%rEVd~lsAW@vc~G8E zh5#K^+{V$m%L};r;6kA}5?~t`n{d_s&`Ot+)zAbSm^IkB?KMg5sC~SfUx?Iy8ul=t zn6KVIZy8n7sO%H6z$whz4UO|rpZ0Xr^sp+E9s+?UDdD3`sSHw~dYNqXPV|i~y`R6N z@MxZ@K~)DW6Eo~(k#lvraVqs=zyYTgNGOc1GtIEiLARWbG`t# znvSiYQi_MLpILxeBR~%VZ9^w##!rL#X%{BGX)3&XXAutIF9t zPp0oX$8!GHscoBmXu2i<0tUxHb)2WMhCQHg2$L$0q*Wf$Dr5ikf>z4V+sQ@1QR`ST6I14(k;5z=Z$TRCE_aMFS{jLrCwR z?f77!e!(KO{T@Z_{`s|A9n$M_vAH>-YF-8 zx;!2#^mIw_6<37r)6>iSe;eEkLDUp{HJ|nvvb@~>=;2GCi=(tGp)X*~F~Jsw*oBH3 zkf2K3D4=|Pr7QEdRj!9;y4BzeXDr#j-QW~j5Xrq|xQ7?`{+{vgraSQb1^Zya&4<2- z>22bJ*Be}WosbYCpw_A5(P^cX6YLFG8DDP58Nk~?3-Gpu~0d5$V zHKuE{&6|`w+OMatT1zzCX-B5_$`Q^zyHxx0bm?yF#9=Trb@L_;K4d*zi7iOFEp7SXTkqF{T$>GU)rybldu_A=}QZ3@!Ky-zWR%|pYHwNtlD}7KW_cY3ZfyZg$CV- zR;4tk^zj=09eBPrc@HpE3(-Ki(fzoI20iwB_y^82sJzT`{Ue`;dC+f}=jsQ~!`UeFV87IzcQ(sL+tpvG zc5JKXH{V~kB^9Y56e;M~1wXE*8#=zG6!2JLQN9v456aRBGX)@&yyK) z)aojIhD_PovQDnjdx)Z*zP?a?4vdz?L3GumpI-^le|df!>)FwF4&5r=04q-ASRaA1 zK#DE`FOztDlF<$Z8DE`rn+-8ObLbk8Hy8hMYSzYL(%Ea$=P(bc1Rl?wI`^2Q#67t& zmyD=i?%PjWXK-k7)WwH=dt9_#ZKd&--1 z^NP(ANAUW0Jgs*EZ+@54PJQOz?MwFeZhKN6-+TvaYTN}RYByvxB3ipZ5dqOMi{cu# zydKcL-oXf$b>~{6*#nB6#?QPheTGm`S&?a?=x4|j#Soe1L_I?$ z>-6_p<4&9*b8shQp~js!L#VhDUZxH*9}V9)l0AoP-3?usvB!>tI5h?d9nQ*xmNR;0 z2w7BVme=Hhk zyrywmh}E^&3=1X6rxQU}XTKyLY2ze65Bf}!8hs7=9pICF)y2S5w|SfcfJCkXhpny3 zmH-#bdvp+~{HyySzlT0^G5I}jLM}h!el^Yc3_1*2TYHqcuq|ZQ(?E6eGg56Rvu-20FM(&F?Tl<(9M<<*2p)| z47*}Hdlu%NaNMtk2w|a|NxX~Ap~8%ZnhCp~Lp+EA!vVCWB9;q_cwA%sgtmvHbWN^c%#7RC%mJsWDeEw!MD2R*LS)HSS3g ziwkE6WV`kqu9y@zpo3A@uBrN|2va&NQ_|2mQ6JK-aNYN=`c>Vfrg`Z7Gnw?w8B5mh z;!=ZWoGI6B^blQEd7(1}kGtnu=dsS0>lOR%!(W6KY%-ANFL=BODQ8TYS=B9eXm1_b zLSI*3p58*$<^iFUBbcpsOX_JGZo@rNOwq~ zovZUY+(BsYexPLGW%bR4=sX>XL-2N{6Hxq&mez~}Ah(?gJWqOCIo6@yt^mP=X@UX( zn6eC&grC~uyUQ)gPIIkeb*C=YtD@i1S05_Wy9IZ;2kD%ZPSo7QD$kKR)lb!gb&gP_ zrhhd(^v{txYAdd}s)juzbtu(&`qK6H9t=oA@91aJMEID{k+pFN262<-1w1D>>QU3? zP-auK5|?mOn2tz4nJ=I6f=w;#`~`)BTUKStJ(r0Y6l9xNP(`(b_|+leLjDfNf%Zv9 z!8Kqv6Nnx;h1~6VfW07*4?IH==cH!g5?_4%lytiDxmE^QJjy4`znw=*Jw(A+l>2zhkh#U(W)DNi=I ztYoRFI&48GMhg^1{X3xsU470n+=Hl(rj&Y#1mB%$Q0nJOkc}mJbEAVCa|MVI5dj9N zf35&Ib47qbxnCe)Y=imBsm0lMFn+uL?Y-lBMCZTL=Q4p)Oej;3dkuPCLske}NluuK z-eFEGl%xf#z6Q9XOH+#3T<5+DAuk z`4LYTv{@xbmoID7>#GlVSzfxSRK3;z03{X`ATXm-SAVRquI z&LG2RxFGW%4xyr}spAEpFY4$AP9Z_g^L0#6NMm*GlxzY*e)>5}(zcXmQ@2=Y15;w; zH{cKdT*)ojZ53xksmrD!FH6g)Z0oXd(9cN)x*{R&jN^%D+l>LAXsGyVAXw*(%MGtNI8mc>E$nLW^_m8i zt>BE{SRh`bAX>Uzf(;Kif1`C^*O*BSnaAzcC*5orq7Wj&ka*8uhHNAeVW`CCi;(Rk zA`GGVd=ad|6PlyhD*yM{0DJK>P=*etpdUgbo^sxsr6C}fWqCmXdjzLEZF0Z}LVLo& z!%^8#s>9jeB?XBgg314IdeH2XZJ?}YFDV?LVyLjQ3eIcSj(5jgTYVcs4?upKl1@@!Q`d2|={fYBvkX8YeIOh1nSU~U9%hh((@DJ52miszy@B;WEXHLx zI&$iy9witI4?G^u{(7R&hmTGwJ3&TXFMrU0A+Qwn(}=)im}V306;H1GxvNzK4j69v)1OuMM%$ z%~Qn5=JnMp3KQix0PBv$i9r%+HY|L~+C&+Bn)yT47MfI4$@581I(QPYIO~HQAXW;2 zmGx>cb}46ezK(k0Yk;Yju0I%%ZHF3@alvT_45to>93Sitr^X>nVfr`1@6|ar{x%qg zHRdTYuG{!$JEz*ZK##wX!NvueIrw=PZ2Z1CgGCu+X4CsIXYlZ~WHet(>C$P~GJ_wT ztTq@62c!nCZI(dWo5k3Q8mL=(`QY7zu{Q>sGNs%$rHbyKsuzn7EuH1=Jp4WO&%`}e zHRPv#pYcTU_Y9TxK3%40;npKijW_#Fxvn43Vcd0XDCDRMxQ1eg{UTWY;QA{7hXP_E zD&kEACk?^$%_cA0;qu2*ePIG|2oQL6k(+-}`+f44+fC~)z1NEehMVf58Ra#}1@&^? ziSFLg_|0VG?c%lidpTaHTI{zs-9O3C)Q~@Pl#&m~4#Q^VtFoEFC#l+whDo+`+SD!R z_K-8C2^9?)`#6ue5)M;3mH@ZLV=n~wskGjPZC=Y5s0f56su^kRw7p<$p@dYO6 zQ?u!srXzQ=Nl8I;RZV6wCy|q2kA6MXqG1yHCPbnsG&#Nk{RAYRRHEa}T#MY#!)qVT zL7G%aFF5N-pU|2sfJ-eUEV_xIzO9IsQJhS_+pjcZIARRf_O6Na(hUFiz5zqdVY}5; z_T*6Ek%Lhf2{kxm-2uTd0OGsL2odLVjeK-qR4_Rb&^76|akUz7NlD`2YEDtR+kz$9v8G9Pm#$PGhY0+}#%MLm=~9CG-E zX~|s=sGE0*&nzceyLRwiJrOfXmVt@w*A;|PO}D9wj$$qq3*9C~r*h5pboO$zPMc!R zMN-6P_j<09LQAEDDv9$blDx7R&f-OjQ3`X`Gx?Am=1c+b5}^93vl;T6)oc4(wkx>2 zZ};{6gF}n_IZIdlOZCYypo+zFPUzqVaFgshVsslquTZK0zl-&Q#=Y3UJwjG(4XbO> zyTE_~;hHm(?QS@2xk1OoalX@~A1A&7Cvz~ZB9s@aXg>~pX6M!n72d;@oj2`yl%4jv zeYwdK-X!FX@K$lqwPYY6j0JeF0f7lx7jhRxU8Qi!{o=0k>t5i3ku75e1-b4QK?2Moj@)gu|Kaix|c(3U6C*#*Amz zDWSI)I?B z!iMp&RHIquM?KZ{qUgh^CdM*n=HXj=B{y@KA9qjfL)Ip+G-qmY?__4q6BXSV8?(C? zQcCZU{9FZ=?gNnz>B=*q7jeEGx4js|z7+4B3WRQ*CSbSHhD6dnEAq6Ysw+)u^4^LQ z@V#6^%y7!e!Uy)Qtb(~ZRp4+Mdx>WpPLJJNHErkPd$`xvmwoMgo4)OP$Dx>0JxF^O zwAa0>d8IUt!j6*qpw;v;y7x#9vlw?|(K#A~gqTBcI%gMRzVk-j3k?(>Dxh`7O2ra; zFXE$Qj;@4hUp;S~pb65|@&;BFKOF)1_T^w4rRq)yqyvNyZ};k0*#2^KSBL%$ zvB!8oe0x45mB)QdJp+N#bW^NbsDjp6?_#HTaL&swF*9oisH(EV`-GbU!R?>TTbOr_ z0*t7t#5+k;aCpuXH9A11)^Pc%CNA8qE)ZNUOYGOyxl%Bn2i@pE<6en(6y_ZQh{$v2 z49785$xW7asq3ig!F0*{v~I!90&}RPMw#*#S2dt6)5=}nGtZ^&nLBBzPF03CDJJYn zV_u#tax{v!A1Berac(|H;`D$~4$C=D9nNbF{d_!?I|LA1Rgp)n!m zQQM9xmC(yTS_wA;7cPS5T)05=F9_jmdTG7uo4g{9T9#c7;Z>XAgO^1E`OmscGMq|B z#Pzp#NxRbvJ}~WeWBNST<>G<9AoW()VIG-L454JX4A%XTak7_W-1XA=`~zMs9p^KL z#LZRMU|*rRBfA=77jSzH>`m^tZe66JFNwba!Bx>GOo)jTD6q_N8`VjjXKQp&)tbsI zt02=ffFECjKcRhjnxWO6J^b-E5`ntAP^94Vh7Y$ZU!$jLu;-1JFYW_iCr;lC%QwCI z^QM;rW*dJ~$s4NAzqHCvlHW`zyuQD-+npV#A*k1fVVg)|4sbb#GDYu6Lr~83iFe!# zH+3E74vqWIr~7)3Xwy(Oe@XAGlqyQykrJcTw_o89ka>$as3D6)?ADO^A|@JQ zzV3V(d%x~{5$fwIm+o`-27<5r_b*<%<|~~`{0N5^eLSm_k6BbXCCJ<}T3{sGn7VUZ zDv~EKKNV>Od1ynyC~;mBhZl)N8wZJ(`X;h-Quon@*G0FTgZKOAQ>(alh*)hIaXWuR z%i}S}_52Z!!-$)iBjlUO9C)%S2|uqF%jc_PL%JJZ?u>2e!0Pg%EZVw-Nv(<e2<=wpPZQdme33)N3=yGbvHf9e2!c8E=Z3w=0EIugO) zw^J~llOiTM1@2M5aZF+j{gtR)zJb1?fPqM*s{DMT&>NjwU9_I?XcG0o`%{_+HcX<< ze)o$N|B-F7W}CR68$iH07Yw#ao+V8}Jlz2sL;x01)4y&3uLk9fk7b(Ehig6nHaocXYs*orgqj5tmZT>Ivi(+;VaOa zD-g6yK2>IMKD(EBr;nW(i*R~1*a%ObrtV-f1;}yiY24JgH*@^3{XOy8i3{+IYd881 zJ97cD6J-ADlg5j+^y}A*sa8=l?Ch>|P*qW3MsR&S7+NEic$U(Et2=6BFl=pSK z!S)b6sG;RExf?_~QCB(wwQs^;K*YT;37MUdtV7X{sVaVq(-s~l^Rb90*J+_*GP$ec7C%?jO`eg#+XKwV2g;bId}tKAT@ zNq}TExCO2-Y>;MRqX(w-yD(%RRB!u{apOibLEIzbCfmvcM~@5?t@1m6$wJ4?Z^G0^ z<{Q*dCbaI{!~K`9--l+Rm*+?2nd^UYhv6joA!@-Vj%XUEl4b2u1#O;Y^g3o;Lw|J- zpixI9zUwB)JBs5}R&}3jQ|hAsY~JdeCXAYUsdG`M3LHMQ-^j|tIaT6xYk!o$(9x>0 zWv8xiV!W=j8+)om(R=?A^^JE)UzLxJC94Ac%ZQgo*WU0)O7X&P)zGmDPPUo3K!-7NB~49|%IGhaG%-@Q=Rcme zuUF?w^07eTqv~A!Z1SA^EJ>l&WA)|!`RjvlmUs;yS`az^0vF%abCgK|=3L?U&j5WV zk^@)Cy2lc=6uow2k4%Jgr)UH0FmE}dry(EzN~6@wmoYsTR2+Vhh~4q;`65Q$Gx6{F zBE-1KyWsnt-az@(R`8s?-hZMlTbG=dxbGEwG|;WoK>8EqYO}U%`SwKi@}gg-Rg_h0 z>h+c15_XT;yDK%1K@AQ=W^7$8XiUOO8q9$3o++0%?30UE8r=7Mxz9t^&!8NiDR(eK z@*)hl@0o%{)x2C?D^}mX=u3+G1^t`PPyByUZ#s~Wfv<`Jh)r>21kQ2I3gVA&UaosC zD})>y&{ZQ0N|g~#ZK&bpDpR&47DaV59Gu`*$I%w9F8H@Thp%FCr^yNpy64IggCXm> zyim1SC#-AG6A^ax5iiUaArN8zx6=ejpe+)6auSvEczD9FNM0`bUlf5O{u1N21c-Iu?nM!Ye`h}1OnVRYi zT1q`ZV&WEA9St@Aa_ZpU(rIJRkjE}F}G8e4x2slr-E5CD^ zFtlOm9-r7FpE~ecIG5C$a)_#88v8d9jX*8%5Gm=~HNAxxfP6z&LE9G%=!$zDw9WoNRZ)QFeyV@fx$BXXwboyM=mD z#~rfDV!i(phh0vsywHPopX)Rd=a`brf&a2~ZVhZSR2|iI3anlhmlZc`M??UUIr%io zm0Tl*%KXom=H{aM0c#IxEVqQqi~0x6F{q$Sa`nR=L=GdFfMNRG^mwj3^gFA9j%H1$QxQYG7vi4dDE=d;uj2$vTDp5jGlLIjD=E z!p!5Wvd;c~@wfVPTCgsE>V`bNIxUyW3B5>X$_b4~=g1K+&=*iBcXHu#4O>zKp#lG8 zy7Big+|H*6_J28?=Y=@+U6j^#AV&28ecG@#JGq1E&Jh&otcpUyqucN^;RMzD1(D@G??7Mdxf7m3WJ8=C&Uzc|e ztj)r6)$uIn$_`yW1Lo&ne|6Bu&gYc#Isz$Dvanqb7)M2#4ipRWaZrn_TY_7?L$9Eu z9ten%&Pcq>e>8pR`=y)v)RJ`th47nOLAWdxq;|J56H6t@mz5>myt_`#e&<0CMUc5r zpRgitkx>Ix`hz631NnJC_j8UN;mx;~r`~ITgfoW}NdhuUAJI1xZ`QbIP20A_XWEVi znl4L-RnZ&^db>%J?UsG3Lm)F3Chqh~>X9NhCDEqqyPDd{h$a%qE@(*vC!y=O zP9_eyPjyMjBueTmGGC4}uP>o9Fj$Dd&P8hzgSeTmGx>Gzh%%p1P9L}tctQ6zcz z_vJ}5h7UUAU!Klhyy;-#3&q~AU+dRjAk-wdM3>0p{g>)tg7)K1KTj!DIM&Q{O2uQo zp=O#O1960PLh~l@R!QA-;5&lkXxxy4Q(Wo}?nSHHe&)b(sjU8DQL<;`tT$Qq#ggRf zi6oQxUo43=g)ouI*DsdjR3bP4XTK;P1LF))NuEVHHwu4RU(&a2#)DcNo`|xHGvFv` z!UGf(`pY%$E`{?u%3w~FI4bb1uB$miUMktO(JY45o(Z+NJtQUxkQ6nE+~ z$Zy8giWUyLc+bHwWBSR#@cvMqFu1*_@?Wicd4uA=N-W}k%TJcJtvC8#Or~~ z?;s4%!N%hf3*i(M88lA9Bnb#ArKXBnBgEeJ%yEQo;@I$ahmPJayShq!m#3(6Fl@V*ybg}Vf}>o+XKEtke*Su4kaJ4le&Ug zXakKs-z(nGvQHO(l0$-)bF3+&Haycrs`*57))AgWc7?Gha|MV+@f&p3C!VZ1SjB)* zr=k-Jmf&3$W0>a(7*1Gu2xHXdN)V$a0#FE**FThr8$xYgXw8BD%^I29T@L6CO^ zO=5qcpz*F{QXUKC@YRB^t5OWh<@o2i(kYnba>mqaHZ@_pnlfB+I0R^2xARcJyeZo_ zAtD=5^5Y7YlNLIksHqBA6&n|?Z7PUz8?3%!`eFvxIxP|}b&J-)$wv+G{mUxybabeg z4;g7l!j6s7!a_j^r?zIFQXbTFlgyw`tuv$2)mp%cE!=;4s#J^I>h%+s!s*eA%1w+#8Q|J z@x$Y$`%tO<(P3fREgLrOG6kq|0F>pS`uYV*l7^OoY1Iu)XXI@i5nJDEs-kG1x=c3I zY*vm26EN($18&L@Pyg9;J2MesH^K551NSs`68y4T^*zIMU2X1dM6f%@ESs}OEo+0$}Mz~Ecq_~4ffb=+rb`#HbHV3Buy`5*U1@DwFe%cwF$NMCN zcdGovS+CSR#rR<_wTm@d!o)t|rYVSShwjF@Awkc|eG%3O*8Xi@k$+_QP6jwyvexOJn4ZQrw@8es`=`K()!hK0Q|oNs=(39Va)(&dQFdfQMSp3cE-A@36K^TojRe|o-nF8m1L@w z5qzVYE9WjJm>nM~(jKMBWV}6wB-HBR2`%t72Q<(~#<^{xG+)CZ<{D;b_jWZ1YmmxX zdh;r_RUB1SMq{42Bfk@Sr;Yj1Rg7E5=kv9l2HNW&rM0LA{p(p7f*M{nmEFG|_6n%64*zzDhsd)PDCb(Tz zl>BbIJg``4*>IN{4rclDZeM=@U075zy?1%uYAt9E+5I`T%L_T*4_MyR0)BwF(fXl% zs)Ckc#OWzS_)z%3WaFi)jrUz@+F@xSNaCWeb99R?6KXs*X%7n??XZ1Ir);$836uWq zUD6D!$i6wZFET)cDzx51qvQ%F)(8ooeg! zEp7!HFL%~joEnQldULPtFS8{K+9@J#b&6)T2vH!BVBGyB5`4v&xpK^wAet|0FwXjH z34^olMQBHBf*CP* zgoc5P!nQIa;b=+^4o+}$@$aX~_3m#MEY&I0XhGN?|8gq%eGkMCG}`|+(sn9aMykZz z3#gsLK;K{u5mW?WbeTjj72r$2>eVMv1~m?FkK9dFhDc8>Vy_J^-&^(4x@(fGX?COO z)`JK|d4IM4X_g6<_b88j`=KihY`_2JqgFcTy{`rQu;&-U&AG6sBp8$6 zCQpQ#0)^v?2wP0-3|mY&T?3X8MRKku7jm`fCpP~Ey=K=vRxg+uc`^xu@ni)X3dlHs zmSJFzK@zEG;f~s*PE%N?U~?w^)7GwLK^08zmu|Yp%pcBO;@0KzVMEi8cZN{(%*!-= zgJ;N;y(=%&^!S}2bJ%4f)b#kBAyf`tk!jlT&XXD9X1aL$^Rq4|=jYYu=ZY?3!Sm(h zaWt?YN(F=-`dFtml~Z{Ge+5jhj*6=7@$6}`>tmwV)b|4POB0=_C9HV0^h_jc<*(U#G3?uDv&D^I89)QrVWh{byO2B z_~Yr9n8>r}01H;)Kei8=nXZT>j})x6yd2XNu~d*)DiLJS0Tw>mM0ZR#%Lz;J!3mC2 zrOcgSuIFdkGajEfm7tV#%%7{E7wr%!5wS=RxUOf>!CkV=IdPvGqwaydMM(OY` zc&LP^Ck0S(oo+VVcEMWU-yItaG>(-l!ccMylUhiM-zv?$K{EGMS2(HYkq7v|-ds;odJxs8Vaf{hd zR2wBk+$pY2Y8t)Dbqrq;j9pn@v86g%^edPG+-p!J`UfX4rIL%+rytjbH+L~Yes=wh z{#YEY9dW){XNAku*9E1-*bQ#}@N+kthEQh)UPcR~Mnb?y)l?vSCBjT`#QsU$V%0IB z)aCHF(Hk(_07r)f?`pwpqdR3PIF8Qdk9R|SaCn$|Cw`TDLA6Y%i`71GRK|*t+-2Bv zAxGvGMHMd@qL^xo7HDpEZPVl2c5T{H0@YCeN}dSTMOE=Mm3XUfuLmc0A9J*j*ULwS z3zE7qADwfw^QJ!Q=tyOKmrXia**l%Wn>DF_QogO~jPx8JeOJAK@@=e=Cnd>Ny|c%| zZ5l#8F+{|6lTA&4p zQhP0?AM_2%$vM-=9d|WMJw1Jnc|}!xL&`IpxF&E)|!fiFVfu7wr z%;bp8t#S5~d8PDt8JGI*ut>_FMiLFX)mPX>V&rT2n3}rCERr%D4$znjGw* zL8A$}yHGjeLxTp*lc@}$#-UN7Xfnv8dyfnXu9MEuKXa3xzGQx0eXYjZE|(wYoUggr zLT1%~S6ud46cz9vab+O^3UWD>-bGWdL6b2~Y!GI=%Kejulh5B?mAiI$*r=1nWj;J? z&=Q%>c%z5MiS?0T#v466Z20Ih&ai$R9w%z)SE-qMtL9AuY`9;nzP{Z*tbV4>srHvm ze;eT{LMDJR!cEsBH3?O34Ug+?h?(dAhS z@dZ5w<7L@GJm}hu#)(-VLo`Gl=K5qAq9-DQGgb94@9TjU>Y~->uU|ZTP6A%5%fBSx zW?-l{#2CoKRB=jBzN3F5p>c7YC-gSj?^aK=K0Z_f ziR-ql2V@JP^R$4L4Tp3DtWr_bQR%vKlL{uo2I@`RFk;mT)xd}}?_tg&wB0xFVS#`U z%+RfyGhRc`M=`)g8Ro7)9X=;5K{VQ*0s3A!^BE>?1J*&+upMYQahX{U6hGuHD9*q> zbhv8~QRX#VX1D@zhdxlZM`=>jtm}sQoVMF+vI896qu}|?K;sy>kgAue%Gl;Tkk_qn zte+@iJlhR<$f8w*4$l);A-3P^hdNN_uVSJhG!&`0{6SiS?h6^-Zq+^BJ1XzhPj8;u zc1tZ$Ks^a^uA`*H;Q;TMD`%a%PJjBz$@e*UgD7$g(EoILk8pEtxhr-|VJ@MIR~YuS zlp9^^KAV%I$tMtLw;v-dRBfqppOe-$>=jwu)yFJuq?u6m3^vj?9TJz{teUs)f^1TE zu0heKLP`9KIjNhLa27Rwo19X{w8;|!r$rlcmngtdiQz;M-Ij)?+q+ImAJL(~A>0Y_j4Oc0R@Rav!P zx=G$ISywQ4600)x1WN@C8YPlU(Zy0p;^&AUQ*^OZkXT|7WQs193X+{Hf;cKwPQXU= z-c@BwP!|u%rvw6wGIXCk<=s7)AWcpSjB}vUZo@^|{X-9IT~su^gL3)DQzLjlzWIJj zR^}98^8JiTEtSOE3J}QZ)L1HL{C-BGmI@j*>P~kvEfq8ziMv#4sU)RRiXUvSVwA`{ zNKu@MrA`0s#Wk!-1%UWL)X(`WF*@e%_1)Ta6<|s>^jDE{s)@%`V4nid5>c^Qg42Qi zamuQ4lEX6?2CwNKyZNV@I{mjDOZB!VB&7b`zOkpt4c$_ztbMws6XXtGUycJqk#?rw z@qTM4$Ig^H>}h{~eefF|qra-#7YwVRY?S}8E%H)&@tKVHw^v}2zVqMq>2dY)^~>A+ z<2FgLMes~}I4glsOj0Tvz({h)5u2nVRS{)9^yM9Hz&dvLii%ZrpY&@@es%gPgWig7 zee;oG$BV{!y2B-`KR2z3Yr$uq;nV{MFmo2Tjpu$TCc05rNpR&Yjnd+ zUiCD*6KZ-IjxRz#guQSctG9do>xaSYxIf%pCmdF*z`ti*#^Vr@Xq~qOOUsWPd% z=1J0&0XlziquoJClrw%{%M6%he#eEayyXYzvMQ~pFK>%t1Jp^M#JEf(J}4W6k*aB8 zdiTj}(e9$0@o_7^6K}wx7p=_ggyEfuqiHyc7mFI5UsFJIiloqAsmfv&OA-Z>r!%EU zizV@Np?*Y1F^_fb-vg~U08j)>XZ&O;2WS}Q(-Xj^N4%@LE+*j6RgTQEDd8!M2|Fm; zH$^89p$122-a_8lKh;Bh^u5$CPv7vjRt@coPmf~KIi|$?(Im4bH&XyH8C9E_rY`CY zvnr|!_<}29DQ&xMiw={nZURiH0vdXTOC2>@y1sWhu2@q~kv6LNjV{bTMcAmH*XIjk zWq#XSeTcA8-&GC=xQ9d?8SWPXnL)AQ)7KZeEkrFG=AOjtK>%Avv`(SYxYJ1vGX}kk zwDxglo76VeNis0(z`1WN~tyRB{b|C_Y~n8K%wYe-gLkEXSYT1E#TrY>;%WSa){aK|`dl|lLZ z=h4VTbHeFQ?a&CEtn$20NB{UZ0MW1p~C_o2l5y#bQ3gUfa74|)ov=2 z(LnO0E?}Iyo>5hO%0anCOQeV;^;wW}goJkZlZA+C`y|E5LS!e35Q4V~7Vpr(y!GfN zmp=EUC2iHX+k#X>0Jq?%pMi6Sw>AS0kNR7F;}YM>Xl`AEQL3p7nYk3Lx~9x!fsBbu zex>so3xrHfoJuh+lMynVXUGT@`$|g|ti!z!F9d_A66(9qJP97&Kf^~8PS(}qr!B<*kM@w96+T4dtn;sEp|jv9tgu!3(Z-GSE&G@rBmCLE|}Ue<=7}8Wq79GX~7D7 zJ)tQ#nk!&1_p$_2KsQ%{XooK)RMv5>fI<1agp0MZH9HE%tLOXS^M&9faNy3XjA0W6 z>jAC{n&ZHfuKC}Pi&F7V?NQS?^~kyu z$s65?c6{j6v0pxGIL*}VJ3i~6E8aC;KCM5^t*f=SL{Z2sxZVL8`TUc7Y}YmCJ~d#} zn-a1Ua+OV5(Zw495l;mOttt_qn&f}T2Z0M<3X^4~foa}d8%3^hwq`CSoSb6EjGweX z#%Nhhf%F0y>g-TX&O#xf1XX!k3xx1Ap$hd386okjL%2s9svR-=%QGCGzMw)Jd$h%I zOt^G+-N7;8u&RmYQ<9pLpy+XIa6&*lL0r%HTe{hMBHR$`Em~Jl9DnQ3Et1Dt+9!*c zSRWBZz+0U_?ZcZ-OihiQ{PySS;ht#y(@WrPS^LW>@jl8-s5yeXg_E_3z_2PoQUO(` zrQE8=QB9j71zAH~VcttMop!Sq6Z|v@{+JfIrBWV$BT`I}*CHumXGMx>L0lwdu$v;r z^g}KZBgR6c@UiphXFbr>^6mahn)s6vMPWP8aZ@H68sAb<8N__?(z`gX)-{nbn2AJvbL+~{5x35^w+)pl&nJh3|IBlV`9q-s}1wnsR80I8#qavI3h?As^@81O1PLjsj!g;BJYbQyYoJgiR=Ol6CmO<52wBkJm zddKbQ1t#)A>xS4BfevR{Q?^IzK;7adOOs7O>b<7fy|!nxQ*b#al)bm>!zWT1?y2_W2mG{;MJ+x7+xhPK&!S+p$^~B z6JlV<{G^@}(M)h-;>XqVFE0is?cn$^E-CH}5B#5|3K)>G@4;@cj+6bz5iI)~^v4fm z6XZ8?aJV3@i{)&9aO}y2v^8bvluH6no|SnYLkZXM0-}O4ysB~_0SfD4=2SNq|MkOH zAI=-EjQZT%cly3|Z(pCMC(Pht6%gHl;23QjjcuC&)#eB?K~{EDOTa(HpejdgM5095 z0hxtkYb*0o-~MMTVl)Nvov-wW%<&V`e0}Nyf+sc0-5p<?K#_Auiz90rz0RaQD2+(DQOPcWT8u}D9VW(xidx~qCP^Q6CRx5 zQeRVS(e1&pA=cFV#uw%(4{NzBQ5z9;_YuqTB~;hi@jGc*p@{L!CzO*;p78bqR@Dyg z9b2r56n6T?PcLshc*;)#z_I$=ZFA2o25XCJPHMJDW8fe+Ybse&qUa=IlR8_s=^9e4 zHjQb=HsvVdroWSHV&^lL6U^uKd{GDL!DP~@u`sQ+*)@kbQl#?=jst^E*bP-gnai+u#As_WU)%(ZdisD`;*HL79hp9? z-JcUGX*6T(^o&rR*Nm}~^Wjo^j57y^3)2a!4%H_ojP-{Sfm(G_!&lojHPHm`pv@^F zntrIAf3Ss9klsB2u2YIesxH~&G?bL}x*!8aq8q~aB7rLnZq7}GyY#2W}i64UFOJ zJ5Aj9U9R+X=wxxBK}=B=ohELgiH5W9ba`H9u0QB;M-@~-&V49VL-)+9RII}6_ynou zP*EOvlqjmNsquBkaZ3F-4n_eM49P@LCHrCnRa@HiH7Jdy&r0UQN;*ebOE;}Aix%b- zPBcUuG}HQWiX`tf8kpL}l7`bx7G-kGi$#t8r)f7@ENM_yS(ItWSu9G<36W$yAR9>F z=hgSu3Bj2|ml~{Cp0BG4M3{12QC#aTNPr4e4P;;3nX4iru7;26I&uDFdU#DG&H#Q6 zlRI4*zKeH%j-pMgq4LPy(N*E~gHODjGm=K%rexIZ9f2Xy6zzUOJj*n>dH7Ehi=hlpF~KGEObwGDo1*0)IhklDVYp zmTWMi=B;M@08-#%(3YPVDyjD7`65J*MFd;-W6Fe` zH%n*HdL5@-S65BU&C@aXY_c_-Mr%S}RT)F%64PM(`!eAWgYn8>GD;`a^$w=pD~7tK zoFs145tC6mN!qBiggw;a+{FnzYh_jZ?}YPrh&sE(wqpSH-h)q84nWs^U8QN008Ph* zY29uz;?02U!wG^X(l+$$WM$gav})+)vti=>lbGwzX$y6>XSAklH$`*&SZQo2eqQ}V z26gB<+9vMTIl*%>mW0*UF-fMFVi7=uNWfD0*3%mYOR8{ei!{f#y)c`#o9TuEgm9;xOY;yJ+#OA}}#Pa)tUx! zy#H3cZGru_-!db@lY)O&R8pR3bsfRsiHio*HThVGv=Ii z=+Dc^uHGE_{caP&VZ8d%y=9+e!)3T_Brve_F1173JjwDB_Np56iwdB5A{krR zs4}~{Bai-frW)zCP!M^gGcAXwcS{#lk&xT%2}3=m-t`GXLw}p{`HnAG_Ps3lQY+2z zp~H6C#ursG=1`K7mfY2s>J84Q2aRDOM8Z*@QzZyDdY-f;tlHSfH18a@a2i##ywlle z0!`c8;#97wz?{7tt$n6+a*>p&&G^fyel3*}Oo+<$ERv!u%2|u?PQEEkUA!27%ix$* zC3eREJtmxTuXNNrR^Qt#{5y9%wtSRxv#(}#FvIB_b3uej{BgpnWKSpx`TR;8{tI`N&zjK3T_xq;KGXa5^v&?&M)8L3 z1L!C-g7O_)2Cz3dAeo#7C4i9urs_7J0a-lkcS0{O{?$}bPgs@PKI)KFp{o-Gjyvh@ z!xrc_)vcxjKYfAW^7}y#9InJ4A#Zf;I8OEPd5jWsdrwY1c~q42)Sf~1w&6b&uxPMf zf`#hv8USLVBDiS44ee1il?!-Bgo)fM)7Uy^DdB{bI*6MSCCK{_3D+k|KqY-?&!s`{ zn)?*PE|Eptp1ug*h=)Bg)#Y37&$v08cMN9La+ixxtpj<3z+y*8jZ z?ExM+nUe~BdNPP$81xaYdCHkZ$u0muzqSIjvfzW@A~R% zclD_6`ux1A9tKELmtSzc2DjWYqJJeKWY{FsHo%>jx0|F%U_PrVD#`$xFI-*2A50&| zi!zWZ`z8$j=r)F}y!+>$^fLLGdX2eN(wL zbAHALgRO5%$G_wD1^QzLi?7stUt(kkNWBhOf0xwXvOr?XGcLub1V}~e2u5>=KG*Q= z!1r8kpm)yNic1$^P<6$ZdC)Nz<{G5l=>u@qLdJ)YNT4|YXN!>cDH6;nJX^wG$VG&4 zCT5Eer4k9onV2m>)Jh~6muQIu4>62`r#t}{%s3dh{PglfjVOSb-C*5Z?%r9qyk19f zo<>*-GF%|Z5W%aHrmFjv280BNt~#QQoZyK<)9~{RrgkFRoZX9-6>Olyw#+fPSdzSL zA0<=Ajp3ps&wzrC4E~RI>8rmP^BHcRuHN+8}LcX z9t6U?+5m*?s)k#R5y$IYxoEF35`HFMEba=9OxfPdrRWd;dwij7T&g4@!#(4<-YOB8xO7w z{Rcdy;A=r(PycIPHdRI1u*s@6BC?Wi+H3;|geha%?t^`ETwbUGu9KFzJxYB4&}b9W#3BK_vN{(Z1(62-(Mx#x1vp+mT#U<=Dl zN{Kqax-2Q+g5Aqht#3{CAkkh^k1xT!h0%7}d-A;T6MeAv%y|Mvoiv@zhmHgP4)q4V z(>-1@$4~Z^X|b9qU^EZJpLY1ec$Dv(ss~qj`%kO>{((r<7E&8?g;GGuovvfRWs<6g zNERbnucb6J?c&nm^ER6eSQhxR+EbBBl$C6XkoELxv*>>cE3>a!hk^H9{=f+rlq$yp z;Yg50>*;J9KoDIsXV=8eZ>Nf>gZ2S}osN5bUlGQ2?n=`^MQ)pIWHN#TTC_=`&R$V? zFp1TeT;U=q!&dMiBbB&ZBt~|mNHHiuOQrbmjX?=oDka2lR7Q7^lwphcN79B8ZQHGV ztMBeAwhanyVdmjpD(L+s78uh84uBoBAz9RA<;GFe6B6w5A}@N%q*Wj&=yZ^3Y}Jfq zcw-rIXDTK)f4ujvjIEnFesm&@v7b49ud$yweq!vgb-S~DGf<^Jzy1VL*BIs#_Y8~I z1FlaQD4s`7D$bJ} zdQvLx=*q2lv@!VfOn?rv2UK4)au z*ULsucl5H6<6g%3RNv>x(8=*L-$r_=CwDaGVt}>|ja`?(tC_@g0fnZ6)`0CUYYPhM ziaet2wd^pbs_0A!G?inAC)cmppotzII`P#EB|J!jy}|8pf?2Y<&l*O?(KDm5M4gmG_eg zT-AfR)f}GIf7|CRs^G$*@_huo&wQU*vwAE;Qx$l8=Kgs8(ole$|Bz#49W|tzc#-m+YToBi*o8Fzo#?(yMNT72o8uB*ft9sIimF?r$1~Y zJr(CTbRfUOe!fnM8h{gnA7w-u*t5yM9$bifoXHNo*6FAvQbrSD5X+Vb8BNsfSu62A zs)0RQvXasCaJa-u$95o23&6d<+LgWy4UAN3a_W++DlJMI#~qhALsQgc6uGE0XMe+; z&s5k0vOM7B-|157UEs^ZwA*j!?#hptQiWG-EfIRT&R8$iHE7ZS$gug7{9ak~u)*POxQb~FHBa|TZ=f`Q?h zGg`iutouq=J&8mV=c;C>Y4Dd_QlgfQfRxEwbyW|YKHHaU@3E72zf2c!xg96x)UI=lez^YrCmNZ`2+SBDAaih^2tJAfOc z4UP&=2V);`O~S?Ln<}TesVLzIF`d%-Y@ABJS$cL)2OCx8IaQM3F?n27Z@T)-|IQ^U z3Hy<#MBdK>?OeJdn(XdPP=Zis1|2F5R|!5_4u%P67Sw5FuI3T^tIqMFn9$#D$%Y(t z!IHu^^tMjN{N|y&0HrJTBm*+lW$B|$Q;}f>v5Xe89-t;yj9d0yMAvHUigg``Hhu7> zRAVOs4YCcl%ltKkXWN$4scLffi9HNB?MAEThp(UTYm_fx{scFUtg|w! zKdr}O%OiKETBlJ%AOmEQ7H}bOXp%Ii$xNZc?i74;@o%Q5u=$($>kE&)4QMEz7qRc2 z(RCNK)weHBP37@i);g60p9|Ci#MR_bIMGo~J{_QJ3bROLz?#0Hv^wdX4{Na5+~TKF z4cPV3MTBRN{5gl)n>qU#4{B0TVd>oM#->zM6H z7(3=VRiq6BsLoF(U!#1dSxdXVcv-%<QwW(@Qo#RnZt@Z|zGhwWk(xe>$$F3u zDJs{Fo^#e3$7q5bu$sy~fe~&xd|SO2_-Yiwz+_T&l1_fF7PFNWfI7~XCZA6nfD@1& z-aYAXK8QF2fjxPoMUU!BobNQ=)Jf9Z;{2OKL7<<2T2)X4@s!|^dHeS(I z@GK^P#Q?Y6LuljbO`?*NJh+Lt;400wy+KXonxy;e=NbX?jqlnK(WAd_6Bi9&h#+85n2+V*%*p{gYrsiJL9vU$ zI8)rEOk@Qc;?FrtdFRWjLwBwOc^%>?8uHQw0(=dZDNvm&VDxbff$LlWJVL1d(nrXQ z54wGeL4x*Oe*5&L`|UjdcUm>ZU%Lheh-XAGqSZ#OG$69pX+!>KLm@fo>)!o@2}ub= zC8$Z=SH1fiQ#1Tds5x23e^*Z4`0MRjw$Buh-qn^H|9*xTQ4ilKt9*_{Qih!?VvNtR zNDPbdAnK-EaH*645P$lM5v}!4q`Sg)rBI#&?D{9DxPPhwtS{a?cEpvJVkjKb5(f>S zi75RNzv9GpgXh$yY{lxFm4C=U8 zu#U;WWms7k2ocTo=a%YbSSBMJTjq{*pl;l`+^(S5)ql(P32e3MhEuc<94E9BbTKWV zHTZ4>u~N#YU2ABRM@0@iW}Jh8$~E;9;i`d>-uu_9{j=O&{NFnUsLg&{$o4kuo&1{* zlR4g~?sWO%v5Ui=SGqNJ{zF}V*g{btFZ1$47aID?KJY7rzMc6`Ka}_o?H6LB=GFC{ zf9dZ(eSMjt*A16(I-)XgTf4ZSt-WyU1*D9kI-;eW5*Wg(u3fQlU8}0bZ>wcTrnRWIOVjzZ0 zfPB085NB#rj!o`ef#4+VIyrXzZsk@Uo?Cn)Q`j4 z%A3+WUBjam5eg-p3usgZ+Zt`FneD9FE!yz5&Rx)Ww)(HB{N<%m{B^{{B9=%Qzpkl* zTqq={w(?My2pQdf6N*?OWYid2k^}RoQW(cX3OY>n{r)vsHIy8=`hc-T+EmcilJpoZ@$0+2et2m)kGjclf52xqiKItZKK6_EY28jF3v#F+meO*}t zS(1;)rL<=cMjVvIzDvQ(;AxEG?QM+71UN>Jk;CLu;GEK3T$fdBwbY^m0?*7X(FijAaw!q zms6BdHI>Vy{p#W$Pao)jc+)l+{&M#6!sGhul45H;O&qH2PjSQDac^H)8vU=l9$IppG-d+#j5Hv@UttX@1I^Chelcl`Qc7^Dp#@eX}eBqoDxSV`~R`` zrcJiwNP6D2wp>3++=oqZn-M9BVjsr7l=y8-CdovK05}}Jyf1#{klIr6k%3($wZ6{zgKV8Y^5i>t9wWxl zt|!ed@x&{=MNc-B>6Mlq#l*>$qBy0cS2T69^{2)LK z34|4}*{!+v22GR{QJXdip~R-;a0QW&Xd`g$&>ng9XXL%_oJg;TY+p{i`>wmhT9>p} zF0`y|GcX-{b#JHJiYAj&&#PTK-BjMTH1%quPB#^GB2B$wu0>6!0s`gzH)gfcz2*b5 zL_tZvdu$DuW8GEc%MLk{k;Q{)FqHbfP66U&`l<6N;AO1p3Xfb8rlokZ;LVFgF6G%FE|)-R zQFDM-E9_FP)d~3KV40^i=q?2B!aM|lD#8NO)gn{InGxw-ZBGqgQp9$htEIW5wLH8u z_6t7tB}5OIcJl0QIZ0!`%4I?0`Oe-lY^%tC;?XHpM||kK5L=|)yuZFZJ=nC58JeE) z@IW_FQiVrpUK_x)Y_jyDhPn}o5y9;VBGQBi*Y~8O{bp`7+1tF-{tQLxUMC&}%(2`5 z;endhKJA^`<(}E&BF#>k9AwHQ*%#R`!feUZbYC3&V&z&!mfpXAL}{8nrWy#$MIW@pB&tC40=#HL^-EA?)WcA37p7UBwsl8Q zNClVz+oX@Vef-IMXB-fHtHB_rZ>hs!`dE+4Y>t@{^D5h>R*QvAN|v3bp*Qy(Zj=hy z-R@HynIi?vo-BuoIfv)8tAKjLyVL{iore^YR-gptkbpqX;N_i~#caxj=8`=KWxk>w zX{S@ zZxs3Oo}b@_YW}gh5A0o%LE&=&#HR&=6guT3hyx&A%uTQ0j!u?)XZQ*gaKXH~Z%-Fq zhWF|bj@zR7!Opz0l{Sf+uYymJW>ndKlLYHIZ!v(EFZ>K~Jg&UT!

dj@ZI$?K4FG=&f$HwiVf*oIi-xp_qdz4XBgc*5xK2gK(rOq55v3eoLt`{cD=e4U|nja_Y zeJC-HD}un#@sWtZ=}lq=iKej3^w0_dNP?%4V&w`1Td#0;y!$A@UMlzU0gY?LUP!#m z@^y0N>t3ZAt`jp~{3`8!otT-!!b?zJCuhD5&Uh-sOgTO(&z*qT++-uT@L2tH_qBqs z1Z;ufMDfuHF&NeM zZRo1nBN$U}-Rs-v^iC~RMG-_?o=H4Nd$J9>Dy8_L>XI()C?zKfRa7--0g)e!l3uJl z5BqV!0PK=*&|GSjFKjRC!QyjmX)jAs+Iv953;Q2df<@}uIDiSR>uJ9EPSoYMkF7ZS zHZ&Q|Ne0b1Ndl_LIZc5Ls9{#F8mt}SQh@W5uG+RZP61E=tL0ZZ%(-lE*I!UdQzq-O zMoPOaY+{zubPjOd{@J|W>593#e|vlU8mTTm{MO_}zP&sdctWpq8Q4hBY2cj(2{Q%) zJ7dqlg&E^gCWxD4@IZA`qY)WW+?dCExc%}UK5ekm@hn>5N~h|57{{9T;45&I!g;pj zNv~i09$tqFj(zT+r<3IJ^Ix*JdR=MAr}R@nUu^(>Lp79 zwUjiVyh6ZMrIn#2EHE(Z2Gl!XivIignzWrt3i^i*F0@x|{Q$>B>q6El9c7z5IbG#C zbNgAtvnH>XKeBmvE=c}4PwT>dpCC?YQiUb(LKWo$z>s7)Y22atF9s^C*WF9=EPiY< zBIKwsNv!Z*b)ZPqbwkn`tir%Q0FX@uOkG7dv?K1{ezD~N(VqKd{w<}}=D(PaY+7}a zVd53o&s!}PCyP#`c?I^Hqz%@cO@C3|oK50HS&1~y|FTuue%ORf(qzHe7pE^5-`?x@ zdrjXle6*uF2JJ@T_Uqg0+b@;|T|7cqH9^pE#V3eQxVMM%oVrW{R*}ZwJI5_oo<0Iq zAV$wA_xAzOx7ruEVoc*AvwqQwvjtga;f*fEUO6IJ3i7Hv6t!6=_chHI29@!F&OJjhBNe zy-48N$n=t@P7c8uSk~ow={dlTfFsBQ*w*&>y{xfCeGgX|na*1sRaxBJx&Kw_)}rR~ zwY0u9E86zW%>VPb>9Vg-}QJic|-QHuW(wAHAZl z+a50L@pcSzO6yWZW#34xoWFE_HY{BAbUnjADh5W?bp~~_?|?7_K)#GSSZZR})Zt+b z;4lDO3P*m)wpGCKN}!jIcD!@9>BQ3X^7c+Q9d?{`x+{Hkx~)vBH1(427BzL&;>uoS z4cY-~e5zhYT>9_EIkA%}!`D}8W0fTs!SI}9WWAdUNZyeaiz6FwpBDEMsGCvV6&W-; zI351(eC9t0^_1kvF}V4%c92puOItg;XMJmVebTq5pcnN$EEj3+oh^%+%Zjm`YsBWC zYqi0Crix)?sholksbsAe1+?}QCV{J&h2+SB2v1%?QB)xmX+;;*ag}m55?1*;^O^HR zUh6u)6aAZ6n-(4lUZt7LTn|qcyjDHUp5ITJL-Zp0AKvZ+#HqdwsntlR#O{H%g~po& zSrS)CfPybbmjabo)zKW1eevbb=TE=qYs-dco_v^f8R(^kTRltcq;EYC*R!NfXVlf_ zj@6-ceC~_2VsAcouofPL

Rm# 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 z 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%0A=x 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∈-7mPaV{q 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

`2koSK0$xFj!0!8H=H&Kx0+& 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�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�`-eNw-rrt#&C?vP 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%0DT$JG>igQ$hfJ=rNY{{v`IrG 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

AgdPawcE3FR>)ZBN6+M1Aw(9S=vdDNT_Hm@ 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⋘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

aG~7|ME{bp= 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

4|q18d6QOfyO_+-2Ot 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

cN0+RHOVn%`(Iz_RA1dz(e# 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

cQTJu8q!1ZYC5)NNt6dQ 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 literal 0 HcmV?d00001 diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fdx b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fdx new file mode 100644 index 0000000000000000000000000000000000000000..1ba41aef60f3485fe3fe68dd1b80451506189b3e GIT binary patch literal 92028 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 literal 0 HcmV?d00001 diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fnm b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fnm new file mode 100644 index 0000000..98f1ed7 --- /dev/null +++ b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.fnm @@ -0,0 +1,3 @@ + +coordinate fingerprintssymbolic-names +classifierselfcovrpovrmcallovrdselfmctor \ No newline at end of file diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.frq b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.frq new file mode 100644 index 0000000..6e7f714 --- /dev/null +++ b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.frq @@ -0,0 +1,1109 @@ +誨同飊15}6貿y_'誮38539%+罙峬4??9穂8)镋,3 !i9慴57鵚矰3 -跾>-眳脳/嚠絆璏18漄;%:8""7 򦿥 +8*,籄* +3 ;疪 $* # 螾􅶝 +0慓<:4! 荙"盞.:0 4*&〢 B5 ("0 軯"4#"󸘵遖!肞,': %84,緼 9疍.連顱06 虯/0!*颷#+6< 烳".%薉%塀 驩鏐!0桪 潱')峵)乀-2+粌9誤-嘷9𕝋(#<$ +粇齳 "嫅蒰$羠檉嵅暢玓僇+共 蛁;<煐誕飮2薱 +韷4碂慗酽賞骵4-錊儵蟜,疉蟍軳莧;:颼筽(﹝昄鲍悃盉蛜礬丮慭讄軪. 觃?%慣絸髣脴齤=憡飍鏘鐚摑檤婦A2嘗c#袹-!6Ae!種鞡G〢 滸 貶)C(o籑!0稦e);8u+a +6*+8鱝Ug゛0$"!]顳q媟8遉96 )i 鸉Y5[.#? )]8&5;$籊-O!%*%_烱"""}0a!$O 筭,覢] +6%媙 +c婸!C鵏#&"7  #2*!")覰k( + O+慒m6,W緼#c!隸 +丅Y $紸K*%7;鞟+󟷣sk稤璔媟w o!41臔G +昒%m7-:M6  2臥' +6I驠 {] 8e>/ $塎7逜Y7 +*鏎Y =)a +6*O&烿昗  +!?, #e蒻y!%;2!"鮍 *鸍飈 񰳇Yc慇6). 3' {軳 _烝9("Y>噏i #疉,璛k 7**U %#O &汮:!:#u󹂡e.6" 骮%邁?5Q霔 +gU/&OY)=]U齳=#'鮠2+c;?M6#76誴!A%瑼7W!+WU ":U/0?;=; 峃祍Y+e 7* m僔W8肊e!讻G ‘9:8譞繕軵粙媟鮑 誌鶡#鵮:8;駩籫 +璵/ 縿儊筸蟁條亅硻龎亖"崓塗煂縯b踍藇 塿%彙!)匛"賦3 莿崷驡韙褌焌") 脨#7覲.鹹遼髖+慍5鹟漎%砮=7 鵦旳鉕 臗2( "#2粻6綐オ!蹧贂昦 >峆? 4譯 +$ # +3<3:8U沨 <稯弉 閿;棌亝 =! 粈> 峍蚚礚3,6鱎矛 儬莍0揂+(q藚飹&綅乚輆%#潜#痗7>箷5誑荱塱遾褳鏻:? +4U蔀m丒- ).8 +;(籌86#馧籝 3񫭍0覫7匼銕 9(0 盩 +軶1 + 铅莖3 4蛧?%颴#銒訐鮱/"閯12蠁 +$鍇廯/粡#乁%軵 噲!閭*C)彂+ ) 韃!O飹?$ 7檣8 玘肗鞿 裲 8譑 $醳7i9 " +.昪7鮪齌亀縆0 鹡 韑' +薠)!沷"*雥媂!O骲9'錤!1 稯砤:#7韋"."罜 蓃6 螰 鐓臛7檌 煔 ; 3 珆! 8噚7 覾 鹸8!梲繎9礪&9檚"棙 +賨稥.7砙7搢!9  E򢘵!=8遹#鞳!祶&7笹M6稸!祡 $璪1鉞鶕?.媽肣#;  &脿033伈# 6檄"6賋觛"齒廠;驪$? 򈍏>(/9骦+!#"蓻[& < 賏籖鞬0鏲!乬亗$廮"<  鱞盚輝漁 +鵟"龓 !6!鵪 Б*"駱虲嚙嘊##,痐&惬+# "絑薵 焅)鞵鵕!鸙!蒠(:)&憹! *鵍. (/鱆齣  !6$(%*跭:$<%縀6搼逩"閾0 艖 + *薍醙#蠔10─  艕鵎  !韆瘂蒰%񷶤颪%誘 # +m憁 +*輓 E4%:裡 : $疦,嘊'"9"蓘 髸)緽; !'7塉7<閦齵 薻葽籹9棞:㎝虵譓#颵嘖.C":,##5習7'!%慚'<17馝慳򿥨丳-? +颷髿烼醶鶀鐠鯋%8& )9:髏説穔蹆=3墪" 7* *5薕0!$袮%虶# 9( ( 9 >#.7 8#3#悱絅 峣粁'"9譧 廋5"噿8 2 +5 +1 6% 盡" / 橭$6)881"4' #& );2 #!#(#(""#;1 &!; 3" "籋 7$ #! 󎡞 (#荄#"8 5 +,#$ " #"- +6+ 0  +6"(4' +:%96 :2  7 1 誐  5#" .99%0!, 6_?籏橾1鐆7廇o蒐隺8蓷潰Y玝肑瓨僒怼僴硹 +籟!峢k時!瘽罼5僩虸髛鐫珜XI鐟t(厠!4*{e8 蒤.婹 0-0 鸻&3-(錠=  490(6(3)痑O 0/"鲌僗,%!-!'>) 1鱌絙( 81 \5,"0藊 +7稱- 4 1橵.+ !鹠 󽧦汦0隒 0)$颵4=6晵𓵚 2跭"#軵, 羅醆4镈/򉸮 +- 錦(38 3/9=絗粇  塨璤1)潁, 鞼&稰.馩'(鸔1 驟:(#隞4譢"4 "'軬"(誥汿1/&*) ( + +匳,軶縒3鱈( 酔3價+%鉛 讗 揚嚜譣眕9厇覮询粦覣 嚍]穖!!鬆鱟1% #9 鍃 }<僜 乄 1螷=1 ("*#28 +1颙罬$%匫荁隠鏗睡=儘玥麙譪揤蒀鵶玨#雙/讍釛諎焁臨2鸎錓翻4碑4褞1獵錑臚菒 媜$;?臕9]袵%3臰!儏 !镽'":; : ( #3"!7.廆 +錞"橬4盦<"蟖) 8儧' 6,穎 +'( "莔婰9 +!=霅¦覶 蟚漋焁荄锧2!+"$貹卼+#:$<=5)"+軦6>鉋烱 祍3羫鉩/ ::' 廆  2 +櫓 亾 08輢!璲&錎矴) $璸醗7 誐厏 鞪#*韋5\ +4桪/:?適羬 駇G "%,-旻$?8誦8-昉 齚655: !/僶舼婫򺄞3C馜G񌣯. 1匯綁 長.議/* 8舚78 4閤8鍕乥 +5馜゜貮稫鰿袮¦窉#/>"/7) 6)鏎7? +#荅+ ?1K 6"Q%工塙:暆-瓎>馻託龍撷&+ +%)螦虯 !1礍誐&笯>9 +%昹 %/$縩/O廆#3僕;3-袲<婣%/箁--廋蚚)髍2>.虳(袳(/&#跡 摫3羀:,勋卼輶潡檭癀隤瓉77#+眡}鳗*:盙8鹻"峉:=%烥8 7 ?<6+"4% 鉊# 87鵴 !泋%莥憢颮〩璊塏  莤 0 +稨鏞c匧!# +󀶸"%= +!)' 󥾳摎駐薬<齓仸<瓭螩烝4'硥憞舊'搘褣菦彛礿廮讌>%ァ飠=墠硱諑昣慚.硁々)i; K塵窇 k龥(! _踷8璆;c"獶,鮠"厡!譴3誏 +僲鳕S"&婯虯Y峿"7聾c1瓃(褘S>鮲m2卥C莽岮o璸颎𛡠滵Q絔 優]醓3:8U焣桜韍 "閜i脩!)廈O脋ioS笰祙U階譍I c鞟S墫酇)眝醗Q稧k酇-#顯薊K骬Q=a晐絰K>o盋Y8 軦"u梟+蚼Q汸 體鐠!9麆e齜7?[7貼憰k 矻笵U鐌!遹塷稬?.璒9鮬亽隕塛 墶[僰"蓗g+!彜u濯閲c+漿漼_37雔譌_丒#鸙臘Q*噀籘K﹟",0!馎 2峩S岴W筙 +!I譇絃w汥9a>錊S紹g6 6遧k祅"! 窇 鯙 $雭o雖7藄M#荙藬﹥沎峇 +僊菒(盵礷蓞峑-閈憭⿴計亁絩笽8()雭墮烰7儙僥賰0繈勘)%暴牛矲舿硓匧薘乼變=塒莻籐籷賊=&87 媎訆8鉏W# .烶噽 鵣 &監&?鉑"8!>厔 ++軵% +<"廍輅 薃$縔螮-#誇 厹6#=7+鮌 痜 7 #5 嘑=*輡(絫説 򄁭> , 礎橯!4 +镻 &%璸/ +  譍 塇嘨w# 逨摕醢 *񫪔)(& ?儺>9 %""虰漿"檘9梋"沷7$蒟叕玽 #砡 4鵴0 !輑?7"誢 儎丅峾(蛒&%慺鞩4"33玌 %談臫梀旴璠1玧'丵!鵍+錬譙礘(烶鹒談4齯馦5媬罵4踃6=嚁譖軵絓璚,峇籕>穃蓌誝蒕罦鸍晱 +蚢㏎ 昢<>鞵&)遃;鸏3昦($,锳: 匑烠 # +駉氡—彸;6:?爪崒=嫚梪匼縃-醽褃*穙…-&佶褍摓賹 荧鯄锊贋.遼菬晱;璣銟僀 亭?緻7'澂竣蟞(潐藣醫觽亼 +裃貯 厐/蚹蚸鉼%鹴 4玦塋烸骯郦貹鮌(縬舖疩;慣籐*蚈螦踋'$ 臞遠 僜𧼑/鱝藠卙慟8>镋 颲$罧鰼: +橦峚硋7肕譧蚢鵐臜">乺錥 ;?(;砢鲙6醖&怜"< 7螶]?U%!;M% 鉓W8 󂍭a!e慉#+["# +*稩_:蒨鵪场齁嫈>崅.齲暜泀縑蠆漄焳 踾丏4罷莗峛覺蹠稧雵藙沥誸鵳> +銁鱒嗓珵蓲譤跙?駒獶6肐繌卆眰酛蚿嫥 薽誖鏣*潛%乾 +J玚瓖 鏼龤蜄%焈瘡.駴+賆媑/4匰 菒!鸝&颳 隩 裮彥錨醂>儀賫彣 鵴瘻5鬄亃1鶆S搯檙鞤晳?ヾ 蟟龝"峧〥>酅潝蓋%3 !#*0";U袾=仌 / 貯 軿* + + +駆?2?,9'旲g輲裖塉M砆c 鹲:!彵媼!廉縞.37S8昩 錼釥6e * / +单乶臚*+乼# 8-鐍 睄硙棗醐转亯揺O";蓽/5 薃銤酻跧跡 +絏o +8S裫璂璥筈藰峀$蟟瘹縕;;g 羈%$)驪踀3橦莂7踦疊㎝塂>噑颯玀'羆>鞶齺檆0條錦岲諝&鉇<臝&6塲晆:'!縘艔/ 鏙螈,#盕珄水爪〾虳=觍輞揅2 籰穱 +3沝侑齉.弮眔莣铆  齶  荓  +鯒, 檞 +漲錏)鏽桾0紷厇+焍薈 ?晀'瘓眡褏藒揃羗痑?軮籱"玗譊a,麗%旽岾8㏄蓅6/穫 48臔 蛫褨瘺媞 #󘙯覸6桹禆 +'颙: 厊莄8.厷鞬0誒&載-9 隖2峮橠8絠 絧!盄褮祃泂蠈&韤 "閎蓀荌綖諈"%醦踛瓫墏珖驝仦閰癞9佻釂Л+輚窇 亞4骃!鵗%漅菧闂醥鲗1遪 +筃、<舧脁﹣鞶#鲌*韀骍)烣鱨キ 銐7棢繋恁匞= 搄!稺軾住麌3蚲4駀69賷鞷砋纽烱韾胊馡5蒧荘艐絘鉑鲿 乄仏彃)崲 櫁艆酼眖銜$補 $晧搱&罥墦蹟噦饯覨笶乲$譢鏒龢穛)'硑鉌崜輄,輁㎎卛櫏荕 .縴睏(鼲鲾E;訝慻2媙覲輽乑鳡讃揊*踚+%絿(廲!訜 鼳>="跩&塮羐3??胦+誁(酑;:6筎0礒('逥(*噁亁% 1蒻3/,稤沶7塇8雑厁(5鸆&〡-羨橮洂彋臡┅'讱泤噅穌3踸砏棷覬乪誑鏦7 嫲岖矪7醘鳈 *齙檂!蚎鐠-/硳 萤 弇" : 珇u%齳鸻=盨!闅26+憌9 頀揑8#輔 (鳜舝縈﹡"(53驜 +梫8鹐% + 嘵;晎輛7儥蒻 賯筧┇硾!#. 弰5> 籹媍疈瓆墑3#+/!褔璦汥鏮k誼墹 僶7邸蒕鶉=輓4炸9﹉ Y5逰錶郓譺媋霃僠吵y鱧脀 #涧 肗箋 +墺L梐〡醠㎡療$檨廳 懍卶8繙擢9筣6峩憱晹鶋)鯛罖 +酙=蚔= 憆#賝 踙+ +=6!!觧眔98%Q+馝9# 僀! %+#&?7 鉘 +<75獶'$穉-+貮0 '-&7A7 +0-6 5?q" 5#覩 (7!0茾%"%/袴"璏'03# (隞=9 鵨彌 -8慇盡 +#葽,峛'瑻3;汚 礚0 *5鵪2?!5&:+慟 荳譚")8 "鱀4?!)鸆 $閙 隒 跩/逥8 P锳!9鞹!(%蟕 籬( +檷逺 )9 ."=-# ,桵 塁% *!< +"񙘸眫 錷棥箏%<誏9&/$6< +璍旵 *&〦"*5!8 )+ & "0罙揈9%:!虭#!桜% +q璦邅"裃焇(籹%c笰駵誆k-"45鰾W9婱6;g濉<5s>i 礲嵃m(蟁[蠘e罞漁齚4e? Y鵃廞鮋g"荳裫賅:鱇# a鰿墧'c憕慠>/隫獳 僓&g墜魽I馼棯%[>:紾3肈烿蒔4<韎1U54絘 +E絰c韸 u烞薞-鸓Y檍(鵔鏎]棰5#鉿洸 卪荿 o葽桜;裯 85岴?;+23/裠&5儍韝箘? 輈疟覤螮!;璯*痽K쟧鼲+籆m.蒐] +7褷 8Y2岯;:" 働'){遟 ? 盧e=' S=馼跘譆軥烶薺,8Y)ek僤螧6 + 譺a錝 A軹 >鉘:丵顰k 揼汧"M翀1跩! k鸄艅󠉩_-鸓W硠2籏 舼粸揇>薚I7籛 *祬![5<亾;鏣憿?葽08W#򕶭c!婣[5滿7塜觘璂厲1丏v賮鐩髈? 韓n? 茿塭9誷顳諟8髆橤螦薃!顰盦匩o絍絍=4U9錫雤檏8峈' +鍑 +馳"*0笯 A軮:4" =07廠賖/2>)+?&禇+閎) (.: 3)乢-媋 鵝8) & 〢遀 (*蒅 )?)遉,:񅜮鏬1莈) 3.袽 踗)閎婡%( 31K)鸇&/<貴' 玚4椋_鵯_鶒Y蛽s釃 +桸W 昛+ 梋5訂猾蟌鐦昋Q 弮'0塂瘖鹶薔 +絥5/ &鞾 +%#*'0#  焠 . 9;??籆:0+8$譆瓌跧蚥 1/'錔(烵:酘嘕貹'嘒蟆?盓 錓! 匼刹,揈霕;#踑鞽*#錕 +羨9=贸肂昤 籇 3璚9鮅#莗薆賁昺$"&; !蚛 !颰稦! ' +砊&:6 卆#' 慦誆-  9(,%% 滲4慡 )韐"?1(荂+'"򊁡"0 "=%廘箶#嘆(鹢i  1?7塊 K= 縄檁%8袿義 .嘺順蚐!2譔莇軱褯砶2,譧馧脪 荪g弡e慫鱋覰岴踄7>7g憦/6醼裺7轂砍縙 󘳤 賐a9 M繗$"'箉弲 颱嘫 + +霋/稥66"彊難厈 17:+ 邭 +=#羱蹕鞼  e 9(;費 Z%諕 酽態 "+鱻"7菕𙴎乮# ;7m4粯 針 卽4賤55酟揈8!櫂 +<"蟸'>軭7%調 +煇!髴2鵏>鵄砛酻駘#蹣  籸񌸤8, 8貺訏"瓅筍煒j# 3(絚誏!-񆻿焳򦽘4諄 飼񱵩4#馷詹祘厎5 觢>覯絢' '4c盄聿閇7 +?酹礎籲M譠裐跲?鏡 %4鸧颻I;眿,8 S筯K 8 "齪O7#!A厫Y薲遡$[搎--*"7 +”$匒󍨃貸]噵7UW#袹c$> 8m)󳕄8! a﹑9k閐 $[鵯]疉锳e#岼軨UY9 誥! +6廇i沵 +e[ 粄塠*m ";漲5罝"#"q/齶弌 c駑蒩,<*c憌玹烡9 7僴8齩S塁W6蹗S6峎S9錬疶 9 S?閙廌/[籐!&1(2# !%換!I韇鸝8跩S弴9裦10&筏賒S鵼7G [ + g%!汚 箎〇 6 (筨颿!5;!"儼g婲9 9a!渐  9_ 綉珯a7鶘莃羍e婽 #"? +龂 韏!婳5g乍丣 礘錋]#駎!譿5 9c缨#穥_卪漮鸘 +M珦峮 9]誰薩S$;+韝/2e"!刊祴_ 0u漄!/8O(?W$懇蟦W昁U5麚蛗-橜 +6k&9/ 莢漑慬i?,筺蛨)O卥 箰佗硢s 穄莮筬i 8飻/蚖 墷9q!!鏸 Q-#S +7讬U盤誣鯏邖!(阀睈 0蒖a 籅8i 鶗稲S賛 1a +8漒翞 箙昐麩 軫擐噆5%/廕 3梒譔酈 :6 #W焟嘔7'鐟 邟遷a# 齫񗚯6M箤%!裃k┎玣#Y獽扫窉媔単# .晉-.礗絁$,e5鳢煪M紺k _7e祝W蠅"_璶W񘜐錧煝鳍噽8 9o2堪嫏7廣7崰躬"譸Q鱦8 橞-K獿荳 氚!檼 +仈+飡S;鮦嘦 ]拽僝匸6 +8 _臸焄m9沴, m鲊, o峚飃鱩骉雃嘍W煄賘慶 +蚏癁縖7髚錙褎M鐅GY憏 +.!G2%_6=𨢃莟痡鵦縅W鳛儌rA#-  8" w絤匶c閊!'6絼鳒麉 o"S慒2"k*亄醍傿O:儁;!#K悉)45#?譵Q"揦9檏"E 8 ;閹桮踐5 ]鳓裧 +M璠!%k憤'韇 +凯8i!7塏/丼蹜蒫逨K   "峞粄a傾]7鯀艞U-菃1揥k 7胣綌錒8 +廡;!禑卋7 W協 誸c 痝脇 + &舖_虎 憀!)Q7, o漲焏揨? 褝 q_a"鐉絹跕6岶! 话骽 :]媴 3:_穬鞮$U 痠"m﹝U輖跢誅 +暕 粐Q薵#")Go#彃#"瘜( a絯*Y霗賡><"飺6;(_鉋U8 6_峱3"m晳絪驚8_棆鳉+揬k骔茿穀稟O鳏粂8Q y鼳7$亇肁  /< '飏橫 1g鐃$盢$璲0,"9  隦45 鼵6廙驞" + 韈闋:摣4痩1飊彨齟胢7綇/羘鯑籓壊(閨窊齎=! 髞.幛 薟峘烦乷.*慽+谩.痵螿摝廱%鮝; +0鱏( ((! 8-#<昈"痯 +醆3,(旹0)廟罻賂藯8#.韘1%%礢遯1&儞% +Q穁珰蒛鳚揬齲*汯焀繃飪!棄򵦞⿸馚゛繉礐 褈*蟣駠5蒍疭訙絙弧6褕蛺仛鏜:丩:焺範鉍龚婴鉲興篆飉鏛﹐> 菂4噉%泘9 +-)盌飌'鍤3蠠暘硜覶峕硂&藦矰潊蛢鮓┋憇檶噏筆 蛈裄彮蟽璻焥洯蟿璉誱<覽焠 丠骩7觰搲罚7賨鶍耄>嫂弝禂顯潳9溪/*魼8"廼汵?覢 :7 +齬 讔輀6 $輒 !>8臰沞9>85>: 慍5縎#蓂"搒''u/"4!9_?"廐A8鵓Y艊Y焜 檻鶑",!賍-58( W裭檡[7摂򧨳)峼崿滽]褩胑 汱U 衰k訒2Q!鮼匬!搻K莯 閑藪互慯 駂0縠 讞穎 +8Y +釆$穥V絭9賜 )馰 = :鉉 +麃 硘厊荖蒳"駗玔"( 6組7髕梕酠繗 酦7 !脝 鵠 貽!蚘5僊 !睊 7!7穕 隯77薳!機9 ! Y邒#韾齗:繉$鹹鼸7祑7崍$廎 7醏厬997慛83絅#莑桹!橩7隺 ,鱜 遖 9 +9;9弡昛#砨8< +慙5隲 漨!5鱱:0 舋疛7慡 9 盬 荲梍K "7"?齋褦餅裯闀$暋祵0鸇/&6&筀 5鱅鵃"覭+鱣 / %#雗 +!鱇4/ 酑$丵  +觙紾 +!;梺颋補#鞞薉罞G蒰$7覰 漥!#%+讏"莏" 鮻玙並5痁  瘞飹鵃 鲿+ 7 痏匨觕 檢89彃!籩顰!彠丟;賎"嫙7$ +廫8繐螷7)褁閍>86)鹺諒瓃"26蒔韕"+#94鏥 藧9颶,瘵舚"$ g8譿7閼&亃蓆舑 6&< +笰 М6$!駓藘a8E铯蛣"1%觷韄6頎/鐋E馛:=悒瓀棥蟔-(!$旾73(鲃"笯5隚<釄)!开藖麪〩盽鐧.雪貵漚麔+蟻彯К乛醾訛 +<遅硹,卻桟馱1檜-肧婳鵆邏荾焒!鮥漡骎'!)5焞諠蹜#蛃罭专>薕臱-賒 5蟜"6嘦#4箎4跴銞裛 噊櫑遦 縲厧 譐 楷駃 搎 瘮瘇<鵦蜑璹鵑匑#颷驦叢踲 :厂 賟鮯报璒颪讀*隮7誆2&羳鯂閖4脄釚癫;怒蠑祏>逹 荈譝%戆璮郗棁9愍-鏐莳蒼齝鵾壆 y 2Y*釘&Y鹠縂慨痲*浓 ?焤W鸐潻焝U#梠┍Q璴&Y讐蟄崁c婮棟o葾摔縫麛'縪墸叧1蹐骾紷u銋櫀僛&_與煗羑+縹k慘俨)晊>絉瘱7u隿籋憃顳㏑gK睗臝袸1舕E#誮-;懑:1伇6壂u齴酰c򃱘#O泞慐厸-薉)稢$ 蠇飾髷3氅筦籺鍡潉5莶﹕銦5.薸/贍焪蟌鼲/>颽;9跠窞(馾--m% 箄/揓59󸀋w'汫23 +筊#"#﹖2=%駆999/<21 7瓬;損)胏3 # 疢&? 9荹鸑鮎墂+7棸暔闃麞=5嘲; +睈裩 +礦焾讔媉丮,輗粰 痟韺丱画 +鮺".* +雛$砄"鬁誗#螭鵈嘙"鱫 僘􊙜潧螾>玂塨 潟-昡籓昺馟脦桳繆鮎憍螹閒6袰輰 +揧尝雊祳瓍墴痸箰璄悻 嘆鲖3盤Д蚉"%焎%񱙤輒逤 嘇鉨9铴鏫軱鞰公蚞7髥洊:-1 隨箿 岺$笿 沢 蛒鶢P 珨5隌 進觓眥&8"逿 !僼񑑦 薧齮6慞艩$#煶3粣9蟂 (踦珱1:獻 進觻!頌誳6 眐 祇 c 烪Q匸0覵1貱 +9{) 玨議 +E9 _,!馯 +5Y9g縨酓(8+$*蒃a" +祕蓳秊禋!'c昛#7厛 :1#繍閏"箊8貿 卭 +5鉊!毳f礵嘠#2櫒-"臞 9 譆$"(軵$ +8% :򊰔 <盄$99#/)#蒓' 颪< 鸄%"(譒"4?3 譊+$6C籊*7譴 +'紺 : )滼髄 7鮂 +跴>* 6盶A1 +4?4! ?誆񾆄 (? )9#媟 8%#(8稝 飶 +镺4筁6梣$塅梤>搑"塃. &!疪)馜"鏷"遪慪 : 烰!裀 +珌0贰嘪翛鞸舰蹚隕韹9晐洤1彑莕 7>鸏*/"縘 +踤褋廻蓕 6誵蒄!離 +蓯隓駋縟 6廈蓛 +9 瓔I噿蚒"#峔0&唬遌9塪 +廦 鬂絀峼?螥!㊣鹙訏g(讄岵羃&駸 汭絣鵹3鉢稪〣 3 &臟盰 錠煋瓡 ; +6򄬊驣+"馼酖懏)暎濂愆軴鸓眂讒 +搇"*胅穲羒儤賔檓櫌橻増駌6 '儂蓇宝肸媭逧 憟,檞鄢7齂梱*蟋%盨&製%婨飤覩馭 遃,貸㎏憈羪洕02礑9桺1 c鉝舎' 5跘9珬 % 335  *1蹨﹎厵漗1s&7薊 3?匓 -莬 '. 3飈' 髲閩莠U#!齷翂"輩 5!?粡搳7鍊 eゝ蒁塅9-姜9踾箠9這’ 6Q誂""綀<肞諅!6)壉-鱷5祲!w#雟昞筫痻虴韰稴> !򵍣<> #璂嘗貽 ;6縌 :煍) 絖;媖 <誃8 稲盦>5锳; 紻鏏礏¦誂荓3袴 8! 袲*:3!89鸊齁鵒# 縋*緼 ,镻璖3 +r 胓!隬鱴"醳綈 噀銟亀焫!儫崺 :飵# !釤9塳胇6舲3"廚:噽鉰4缨綋蒏颻蹏!烻!賺崼踆7箵7 颎"0鮆6諊伲橴瓧獺"澃恝⿹弓塟揂'&蓹蛦#$(艌鏺+搝&龍譗觸舘4崪軰 玤3穒雈&脭=髒) 賳&橪雸揘6 +! #卻>"籗A</銄 *荓4 蠙矷蒦誠檡3璿 ;漀 + 櫐!"臺8鱑,0 菚岐筞峼張"-漬譆 +楝 1y:鐘 儅痚 墱鉯餃踥&8& 遻蚙隣.鞢7踇-閛 +.<梚遲說'q鲉璪/ +罶鶈' +諂霜購6檊3盡婻郢媅瓇嘨8鱍丄肎跘盽廔譣嚟"8$閥裑鯉馤薟7廟貲 鶄﹦1+!鮋岴璱4跾汫僕昇橰絈盡-駙卝<噕=鮜6門&開 +譙"齝慮軼鮐6匞 鼺=('#紻硔儖鐉 逽瘯嚇<鮡礡%贉桭潕"?鮤卥&跘$)54*塷肻誫誂>韼飬搊 鶓 閞藲鯅匨!輠蹨*紷艑跲袲񙎦N5漽< 蟸岈誜3笵'鏹#籧.嘚痆砮"雽噓岲蓱驠礑*統"彅袬蟅#龐鲍荖罝u"讂橭錊=睎盫息1攉礽0錛0瘛鞺袮 / 鐉1嵁脟#橨 +稝篃󙋱諘骫齦 0+儂= +裿驟 笲邟乫:颺7 璭峼?虷s!廣覥6鮶須 8 韓8檝蒥 #'莔$# 旸!搥*&&婭0$$"5僗慹/觨#蜆3 邨 7盋誰6覭揵;祪9砃 雡!潠 +螸 " +﹖!蟨(顯8梂 6+30& 󫬅$%#'廐%3玔:璟滰硚/)&)鵓-;&=! 疪 1紻0 &=)3( 搷>' 򄐝1 !#仚$!'%0 &( *,鵍&(  > !+=% +讚< + 通卼 蟵誷籬 伆B!8*廣&獸廆 | 0`    + + +          +                                                                                                                                                                                                                                                         /|0`    + + +  !%   & " !%                                                                                                                                                                                                                                                       /|0`    + + +  !%   & " !%                                                                                                                                                                                                                                                       /|0`    + + +  !%   & " !%                                                                                                                                                                                                                                                           /|0`    + + +   " "&   !$                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    丩|0`-  +(='($6$'=)5 &) -%0)% )!&!$)4# +""(%#($)$*+()4(* )'"%/>(36 +!$&)),,6-$2/4#,(.!"//!84),*&$-'#&"##&2%&"-*&+%%(#,0))1, ,*$6+**+ &,+*+!&!(+!%  %*)%-+(.1%!%+#) "+.'-#)++$''#,#!+#)&!" $$'!.) $%($) ,+%(?()*#  %$'/*'".'+)%=$(+*-4&%#+(1+&"()&. )11'!7*- ;З檱誨齠潂鶞僐>縛齪岘同製乿瘳醌6擀荮棃弶_硴駕錍櫅資痀󫙻峬4煯镽盧.1梛飅镋噰ウ螗 8覱絨9仾藩贈鵚珳轀煥栓跾潚鍝荼北眳脳/嚠絆漝籨绫棽8茫煟瓓髩龡塽璼:;焼睅寻潖鉗較铵9檥,茛訕煰3絊睓疪泆沬*鉱3矵华9鞾9瑟讁鵱胕"彟驩祫 銄銅繓稰:炸焧蟡軷厰,O 喀髤鵽鯈(馢摚8稾"諞統仒颭.墣贡煢8軺縏弆力,駅3 珷,韒榘鏵"菚鏑檆鐐慓僧鵺媌 瘧霌覴0蚷摙鮛厓譾?摢 軽泏錳%頍鸒隒旸羉韯薓釕筒洡潱''峵祎璗乀22髢粌乤誤嘷譛赚莡򗑓瘶醎賢<蛪眅烴 +粇齳 "嫅蒰$羠檉嵅暢玓僇+共 蛁;<煐誕飮2薱 +韷4碂慗酽賞骵4-錊儵蟜,疉蟍軳莧;:颼筽(﹝昄鲍悃盉蛜礬丮慭珝箒粏棣瓑胻讅軪觃?8叅%瓕絸髣脴齤=憡飍鏘鐚摑檤婦A繛蜖齸2弐c'脽鮨廥蟈!潎毽񆉯礨疍鮀潌酜滸蟐貶髧祱エ縭嘸橬玀$.0穨彔礣蠜霘$莩椴搝>鳁,+7縨璡縳滳蛅馿羾蛡!櫝儻昷筰鸊$鹯弖蟓q梉遉崚頌)*臠連譨`鸉輿絋桿5遧檵鏔錕)颕莂瓪 &鰼>醰辈5憣蟶睙.-肙鉻%񞝖梗崌憜鹀虯踈籡罤樊=乥箮釒莐買蹔鮰遳経(雐筳2颮.穞螳羺僁瑿莹岜/.鱌 +鵏鉳瓗:醷珅潷弋髄筶5%敞ォ譸;爆蜋搮墕崹麘弨0峀珒鍌昒峽惆橧籿񝛼噃輙/ 醪眀席昲輍1'棬蟥髨 鍋覥顱 懕鍞弣舽0 逜鱗蟎銚餄*齥鍀绮邥*)4搆5龐諕覻昗鉿縧潔鵍烳+ +間譭鼶,*;<'艢9礯24誙鮳򳠘箖仱?,*乏絒墍硯鯌籊鹵55摤)窏硿眃乆'򃌏憙鱛釅認璌(莾邆轄霐讋〤?甙梇璛蚥鍣*漧駆峷烾%鏰檃粋盜7悫觀齭識>?泈岚5 蹥昫莽6:袴"%邁锽笴??I洟仯儰眨霔爽櫗癍煫+*))暐肈鞨荋=鯖诇蠗鮠;酇瑽髕隣鯍祾闁崡誴丆證鉇瑼錮麁眬::;桝噐?鞡==鱙儸羣檜賿,+5梞37*氓賄僔㎞肊縝搫讻潨毹‘6鉶:8ケ翍繕卾%粙媟鮑 誌鶡#鵮:8;駩籫 +璵/ 縿儊筸蟁條亅硻龎亖"崓塗煂縯b踍藇 頉塿彙#)﹏彂┄賦3 莿崷驡韙褌帷焌)潮 #瓰跰.鹹髰彄+慍硏踫鹟檷漎閵%匒螥穦 銀旳鉕籠藶臗齯化 搚"汧粻6綐榀彴蹧贂昦駚摋>峆蠌绡4譯 +4稵絯 +\)洐3暒U弔飄暟稯弉 閿;棌亝膝慱=粈軯>峍仺蚚3,莋1鱎痷踖矛 *,儬莍0揂嫕箂賚洔藚飹&綅乚輆%#潜&痗鼺荺鶜箷5颰漷荱塱遾褳鏻崢:媧4U蔀寨砫遜璸m).隝?藂鳗(洨峴賲6梿蚠踰籝 鞟鹺亸疎箺;銕醡婨 篂 鱠盩泧羭蟯峈軶沑讙 ;9铅憏靼厊鵲莖蛧4 ?昬玱菎蟀颴銒訐鮱逥1獳艝21蠁厬$选絗廯嫬楠墇乁漴鹥軵僵憝噲摥窄閭桨+螸羗韃珋迎?氕 漌檣3誽蚑梴鞿噞裲縋譑穝禐霝$:i/ +9昪硽鮪蛌齌玧髮袿匭0鹡粅韑搈醱薠骕泎蠎沷应*絲飝媂>?櫆鬀骲錤鉤褅=1螼 砓砤禌馌韋蹓.桻桺罜绋蓃!螰塯鯗閪臛檌箛 脓煔鵊;峊3珆鶠 9噚岑週鱸覾颖鹸!嚋浚籙礪藔鮒⿻檚彞棙+邾滼塮.荢砙搢/紽9E絳5媁覿=婻釔頃5峲鞳祶统:笹匟檦稸粀沺仐閽 0訓儣鉞鶕?塂僣6媽舗肣铩噡卹飁僅;&脿乨0伈滵#脄檄疦閯"2賋叆祩濠齒嫍昜懦驪卍媝$翣7骹榨>祐9羻骦嚞硦8鉦>蓻'[汣< 邼<籖蹤梚鏲3餁亗讑棴+< 煚=盚賾遼漁銡 +峠龓廵 .!邤駈鍙Б漍亄*誈駱玞虲駧鉺嚙慾銔嘊媏,噷撰痐龁惬齆+鍇漐絑蔁氇焅藨這鵕'賬窢蒠亴(鵥坎憹6肹;棧*乽氍(籜保)瓛诪齣憉雞!誜璙梶-*祔党跭縘蓾$藛蟕禈墾縀雥搼胘逩潣踷閾脈胐婹0艖軩 無8薍參蠔9輎3─/ 韐罧艕鵎銣櫓!艃瘼瘂0桲卟%9絡閬飐釞颪憂籤誘邇穾憁 +荬櫎輼*眩鵫4鉟煬裡鉷濯龗蛝2 ,蚽=臢"蓘5 髸"K綆蹢縱沄塹9檅鉧┏閦汙+鍦齵薻罽籹儨舃棞鵜¨虵譓跱蟻揯蟰僷嘖髱祻蟊鐈峂焬釡胔2#習開厙酟!%慚'<羷<梘3軻3硱;褭環2昉焭繏+鐝诞鸌(佟﹍錖=毛%塏礛玼 +骙>艛 +鵛&3鍁閤貼鵋弹> ?邔9繒稡T舥贇 .6筜ー=桱銑羂軦 僌螱3"鮣 +澅 礍 &駬驫鱺諡遺 薙醑潗読1硊羖馝覫)慳0璱瘈0.?絇髿烼醶+萤侏鯋鉣%&儲﹌1髏説穔蹆=3墪鸮罳/梑墭煣*7!4鲀蹮筊0梬鳟煈蟛棈荎0憸礰銉驤 珗脅2憀翇( 沇儃訒鱘蒘>銝叝烜悱鏯烺硵峣粁矱'駤梙檟鱊?童侃蠂 鮊氮〃胾録0鐜揝媀韲韠醨营鐕 譞悛薣9裏 4璝嫇臷嚛舙﹊1)H褤莲邐笵昰1砊艒荨縡.鉝 ェゝ礔瀣?鸴蓜韅脙铳8鹰$8藅飼譕7韔=拴銏媦攥閴齢砎3筈梲杀錯齅-#崫醞1 瘿玠慉閼裻縍5獲誎弫賸鱋硆砿飷,'塃鉫邎眑鉏, 墯藊臖 +(恚搃崐8璾積.$〢$鯘舏昹1'飸塣翑摗婩 邞鞅祒錩昖鐞儗﹋噒 '輪錭揁酴塸璲뽢绚慼:滷縷?飱岍17廇鼳蒐钞8蓷酡潰e肑瓨僒怼胦僴硹駖籟峢鱤償時瘽鮔罼僩虸疜髛鐫珜X荵讜t-(厠潿4+*9e 鶃%摺.麗嫳螪莴髽-鍂昢儜/&/&銈峜/墤覷番-舉鉒婡焢 _錌經9鵵輏伄6厭挺烢绔蚭(漵 峐蠝/脥觡/輺薛揢焨7慴+蹡/檻穘蠟噹觶賌霊5,眧荶閡輸-鏝箯>鱮焔睖籏但礸莅鲝艍8駄 蠣,螻輯縁鮚>稱褜崋駡4鉚墬橵千雱8+焩閂噺!崝窡2昳#莌潤鵣絥闉盠;鏓7睆颵酮蒕焃賽晵2薶憴=鶊 裋肍"礝譏臔羅賩┉醆镈洬錿鏎脤6縩蒶 鲹収錚懋8蜔鮇塴唱l3媜穵煙-翉'羵鍄脸櫈匔珡潁媄:鉪 鲓鐒塚棤馩櫛誻鏩棳棇跲嵆 軸菫鼴8薫隴"漼覹羥*蒑軬В裍墈峸媻侔汿蹫粎茾硲/乬箑)7肳 +僉嚔 :翆鸤俩銗郇鱈踜脌*鳎價*閧蟅梖荴)譟 抄譣泒眕櫔綍覮询钱粦镴覣嚍]穖洀)(鬆媯鱟1匴1 羦鍃嫆厼}=銠荩鍓 ?=廢鐔℡ 憒驢*-鉖粍翈2遤暏(閮罬签眗蒮麥匫珔莀髵荁醲隠鏗睡=儘玥麙譪揤蒀鵶玨#雙/讍釛諎焁臨晘2錓翻4碑4褞1獵錑臚摀瓘俪 镸鐛臕郫駏穇]鵰璈賁3沰蟤嫞艁厯鳔- "鯓齖盷=痭(薐=崟穢踁3蒚誛雘霑錞晈鉵齇4嫤檰1玬7"⿺珓)<酘泚鐮'譎鵉'漇'輊/玐>伂婰檋彚%裚!洆¦" 晥漋划瘏荄崯2鮍觭蒬“?輜蛷瓏+N蟢痓>卑<誾)稫㎡駔鱀縶>鉙慩瓚3羫亣#橢/汻氘長媷 塎?' ;錏钒 窚潹雋0輢-雼諆煪軲醟矴觩藑 $粩僽铿 -蟵厏麠駥*潙イ9絻? +挪镚 菄遲適惘麕莙峳訑莭$镮,螃洜嘮%$/鏶+摐憶誦-鹽彏齚󎐖眓懁:.. 頋%雹婫墲藵砳2輇艡玶鹮昮7乵乴鐂匯綁眽讎 鱔潀藎崸洺宀 !臲鱞玈瘲砈鍕輬鱹棜5墝輠貮Й弻鶚氆袮影$#瘔絝(箓匥櫕砵媕3)驲墥7塩菐.0稀++8嚘伐$4%工塙:暆-瓎>馻託龍撷&+*(4紿)< 供:%'珚逪=弤 誐沜鵩盭贄 +轁򁿩 砕酕廏$:O絫軥@僕飊亪粓酾󀘍羮<刷旬駙艀駷睋梽纰2閟羜痎粔晣骳袳穼鍖飢67&摫3羀:,勋卼輶潡檭癀隤瓉7鮌##餂捅*緽盙崬鹻峉:亙韂=媈馲8況7璚邉賠<+酠4鸜 慠鉮0#谁; -%憢蚗廘粬蛕,崥靴+ - 矨觪媩:達監暖稨О卄銇幞&搙嚤 +薈0#媡カ邫酺鯙絖=税 S釟05摎駐薬<齓硑仸<瓭螩烝4'硥憞舊'搘褣菦彛礿廮讌>%ァ飠=墠惮摦諑ガ昣.儮砂)<=錐;鮭K嫨 袯-(#箚 鱃璆駛觾紸"讘,"郡厡镰賥藆3鮸 +佼"馠婯瘝讓峿珶7聾惝讲廞褬(褘檪魿鮲釋鯆2蠞憺鳝Р岮鸄颎0譼絔踼鍫痢厱醓:<賃﹢匓韍穡蛓"粨兂脩鵖ˉ鳂脋壊o裵墋祙閁肦媎觗 x漻袺 冒漜!)裏搿绛眆醗飿贆語㈱錱#&廧薊旻窛骬胈窐邘噛絰墐>?>輈"4漺 郐+漬蚼汸鏪體韻翄咯!縗麆邊齜岪?7憰麜潯矻霅繎鐌鐬噸塷駦覰稬韢.9暡沒塛恪墶繊僰蓗鮈+彜儱侪藞閲夕+漿縵3痥蓚譌誡6鸙繘彍*讖籘錸痮﹟艦,岯譋嘡0乕鮖2艥棡嘳輂筙鮫賓遚"!蛻矼絃9瘑蠀>麀昍鸕6橶6仹櫍諍搷"跜6!蓸慝 !$酯悝隶雖焿藄梩媬#荙藬﹥沎峇筗遹n񶊰僊菒(盵礷蓞峑-閈憭⿴計亁絩笽8()雭墮烰7儙僥賰0繈勘)%暴牛矲舿硓匧薘乼變=塒莻籐籷賊=﹛?,7 羛訆鯒揘洦立墫W搟.噽硸 鐊請&:飰蟑酨羢鵤?檳釗閝8>厔摟+摉Ё億%疓<色籪鏭<輅 #$縔螮-#誇 岌6僙穣顴媗臮鐥蚻賣錣痜梤應泍顲 -3鏢!'諚鐑嘑闈*艤剑(箞悌麎 鉆鵸>鱄賺,彫閷媖暊艜镻憄飽橺-潵%4匱跦'噖譜譍 絏卯$嘐$w逨摕醢习厳4籢醤薎2珘&儺泋>鮁鱕 銥"9梊粚瓙箈醣瘬梋晸閜哩8棏棶叕骏/籦>砡棻 + ?0醀弍礠鱂>!映?蓈醻崠憅藡儎丅峾崱(酅沠慺鞩蒱Г瓱賙鵙4鍥搗玌談臫噑旴翝鐩1晉'!踠憥+嫗譙(輝憛﹩嫪4閗馦棾5粐罵蹘踃=嚁踒胟沕鶀,脧籕骮墎誝潾罦粫郅裬 +噁> 祂<釓>&.)硤;3頂(鼵"丂$卬,廩:摏誧烠蹎髳駉氡—彸;6:?爪崒=嫚梪匼縃-醽褃*穙…-&佶褍摓賹 荧鯄锊贋.菬晱;璣銟僀璍嫢亭緻魼'!澂竣蟞潐藣醫觽亼 +觛褵厐/蚹梾蚸墡%綒毵4玦丵塋懗烸郦蜏貹(睔瀛銓疩裶羓魾洃蚈龞鮴餇踋莤.$遠泃檽僜:5綉/蟧墛慟鮂墢誩颲玴$.晲橰コ +硋櫘肕祣澶"4>灏賧錥 鼿?醙;砢鲙6醖&怜鮄(儏薕/飋銊繀:??齞穯鉛疺;莝銙瓥铡%莵卂踎撸鉓髜搤镠邩;<'璑嘜硁翋#匲1礹譺雲蓡注<:蒨鵪场齁嫈>崅.螫暜泀怀縑蠆漄焳 蓪楱丏舩罷髊峛覺蹠稧雵藙沥誸鵳>誋銁鱒嗓珵蓲譤跙?駒獶6肐繌卆眰酛蚿嫥 薽誖鏣*潛%乾 +J玚瓖 鏼龤蜄%焈瘡.駴+賆筭媑褲觝匰煴 脼!駟沘颳隩 裮彥錨醂>儀賫彣 鵴瘻5鬄亃1鶆儝S鍐藟檙輾鞤晳璷蒓輱?ヾ1 蜎龝罠"軧桶〥肶潝蓋%繂齼蟘罞椐#蒒恰颾硉遱籔袾=仌 廝蒤9砖貯鸑僨*虭脕 +墰?妆搑胒,泿肰檴蟭輲裖塉酭Q眜觟M鹲:筡彵媼!廉縞.53⟯8:薲昩 錼釥66颣厜揔 昚鮐 +单韡硛乶鯇搾廭鱝埂艧+沯噠1$#-鐍拧睄硙棗醐转亯飗揺=4慥閃<穧晇運=;塓観珴?棓 墽厺肵洢6<05,籮蓽。弑/鹍昿銤酻跧跡噋憐 +瞬鮟嘽𢀓(澧親璂璥灞餀藰賈$蟟譳瘹縕;<;噇 %'$)韟踀񽁣橦擤7瘰㎝睉吮>颯櫋繄'邜>3齺泦沨0禍駹錦諝&<絾1薂&6蔂鲄:羈暀;艔񇐁縣 鏙螈,檍#珄水锃〾虳廰=輞揅2媣 穱幡 +>沝侑齉婼暠.誺莣铆 !蛂 繅 逳 鸚6  +,緼 釀鮷 +荰鶙)桾薼輕0穳厇+:楗焍 ?拱'瘓眡褏儦洍藒盈揃痑蹱軮邚籱仮玗a,洽慇旽潈岾㏄叒蓅/穫洠48厃 蛫闆褨瘺亽媞#薝崕7﹨6А禆-颙駝箆莄8漟澇厷嘝0憓i>&載焷鱢-#裌2橠絴眾絠絧髐蚢!耍褮祃泂撺&恭 /閎蓀荌綖諈"%醦踛瓫墏珖驝仦閰癞9佻釂Л+輚窇 亞4骃!鵗%漅菧闂醥鲗1鐇遪筃、<舧脁﹣鞶#鲌*韀骍)烣鱨キ 銐7棢繋恁匞= 搄!稺軾住麌3蚲4駀69賷鞷砋纽烱韾胊馡5蒧荘艐絘鉑鲿 乄仏彃)崲 櫁艆酼眖銜$補 $晧搱&罥墦蹟噦饯覨笶乲崗;$譢鏒龢穛)'鉌崜輄,輁㎎卛櫏荕 .縴睏(鼲鲾E;訝慻2媙覲輽乑鳡讃揊*踚+%絿(廲!訜 隟棅莁~=&<擘櫚箌菨盺讈鹔郜誁﹙;嫮鐨筎塲儔慲卨'諗农緾*瘢 摘=4鹓/鵟韚蜅塇隵鍔雑絶棫鳠5鱵汼媮焵橮洂彋臡┅'讱泤噅穌3踸砏棷覬乪誑鏦7 嫲岖矪7醘鳈 *齙檂!蚎鐠-/駰 9輳弇 籆 弸u菍暉%鍩鸻盨媢闅停2閔+砆 邷揑輥9輔彁(鳜憫舝縈﹡郀(5媓驜鉠 +*梫岙鹐% +嘵瘷晎輛僑儥蒻觵賯筧┇硾3峌峹. 脛弰>関媍疈瓆墑3+/!褔钎璦鏮慏k誼墹綈!7邸縓鶉=輓4叚9雚﹉Y5逰錶郓褄媋锚霃塼僠吵y鱧脀 #涧 肗箋 +墺L譥梐俊玸鮏療$━廳 懍卶8繙擢9筣6峩憱晹鶋鯛罖锆儠蚔鸋=罣醜眹弄硟檺駊綔 +揌鶁嵂粛禃&眔9莚{Q隖譲菋鞧虶羐訃璔絜遝髬%?纭摖艙醄鄄ゲ漹錵鞪頄觬穉胋d釖誒泴搥?''鍧鏴焮堾臞揙盳锧?祦鵡硶綘譊鵇藢疕慔嫀諐薭懀担1#獷%%鍘籰砲玊裈崄7閄筨鮞厹璃鵨掸彌洣-媐昑砠脡粃.鏽/,髴僺蠋'麐譻瑻;儅禎礚雦櫇*祅8硣穩2醧贀5遶讝&<弚鐋褟+ 鵿乧訌v譚)鹢7璽/ 4龜)舖穤獴摪 筂臶玏 廹"8鸛穋锳8 3鞹钮絵穃搯%霟彇閘悖 逺鮧+塀 ﹞齊揰#錽酫=伀訋羕嚈蛥8 駍 馧晞 過 6匵韴<砞瀚輐;眫轂錷烯菢箏檘硧4%誏訚箹揮嘗&'藷噄鱐沖谦瓝昈旵珁&<扭:*噾鏾脣錟僢還臵:^繝 .驦飭搰帽镺鱬麏錔(ヽ鰿玁0輵邅:"&綄焇0煠丹(梟,+駵籑蛖"輋鸖5舮飜摮婱儉閫馜濉眱榄?>礙嵃噭翗瓩(鱥蠘鵑 暈嚢/z?玝 !钩鮋>鍟裫僯汐鱇閠00#墧'粒¥麅憕镾瘨睌/隫晿叏僓&;<賉墜铣紹魽逷棯&%鯚紾乗煵蒔雿颬韎郎12穐蓤崏醹蟷珪蓴韸酧 叇薞}鯊駨-昻贃璯铷摠棰虐7洸眪 箣荿p/0險鲪眤〕逫霂⿵;+駪蹞僞/裠&5儍韝箘┌?隑蚅疟覤螵桐;梡窔痽78縦8觠&)+卲檕繍瓄墊. +綑沀褷薥疊譇 2薦區艠韨򎘞"'>)*ˇ 韆鵢艂噣雬臽=媠𭙔'煱譆覧駮薺,塶眒5)/ 邲僤龒髗選螧 + 輤節栅盽馹錝軹蒷閉将鉘:建循穻顰貰鏚踻梈翀1叀蹪{ 艅調硘僃-麡墌硠2優駗舼粸揇>薚髇籵甩籛飫暅蹝*祬峧44<亾儶;=漊憿醝%*葽蛵裪0絽蹌薑!璫觔摍滿7塜觘毡厲噓1瓂賮禉壇髈 鍅? 齛塭9鱚諟8鐖橤薃隱!蚦盦驨匩絍=񽛴9仜雤媘檏8翃袲*4羄鍑 +厁憼羋諢漘.儳 憩踂4踶:匽摃慖 蓎 7鉹韽蚫幔玵晅韞;ィ恧2叜厗笷﹪禇錘憠鮵=盲醩憑3艎礲錎檹蓏仢眎.丧3塤瘄D乢-駢訖(亜 憲桩)窂穚碃羇8匳%/賝礎'璕論讛:鱖肎釁6 鱽蒅檖臥蹍*绠鱪 ;"疻眴蹖‖+,飂鳀伅厒񅜮鏬1莈双總 痬?袽沶焽踗恣匛=蓧遰婾茂2(輹峅1蚃藮譈敛焹>)閶儴綂盢貴蠈駇潽,龘郯穭盿彠々扦椋譵鵯鶒褢繑蛽銘釃鞱桸〔:峏潬3嘋:5訂猾4 瘾4揹疧鐦1鵬蒵昋譽弮壃乭'鱓瘖鹶瘭僡銍縸薔脷谉穮電鮬洷嘾5僾眻  +蛚㏒0饱0痳3髆颩#挡%健邠2鉈筿 鯁忒洉馞獹#櫐遙背:焗髠醁/+齘揕盓儕噯嘆瓌籥籒祋搨8 馽常韖飏/暃(烵嘯 纾飔滾韉蠒鱅.'沊髉嘒閸蟆丳睍癔晆覸穥 !觱 釈刹蟉-釣霕;藍昘翖踑祝焛蠐鞽#給痾叡羨=贸肂昤 揜璤駫蚾噮;猫 棖%薆彤憊翚輨賵"鉎莬橽罯堿"鮜憗蚮儹筓.晄!9鲘&-縢诈<袶#雂鱆鸼鏞2瘍駁誆訉蓔 ㏕,珮閣厀滲7輮叓=棭眮烞遣(鲏盕昸5馬邧結憮'#"嫋菛搒砇麍<%箶鸗焂7讟繖邰(眲訁藴盝泭褗⿰髪県蓂藝砱疿縄莗檁翓玒籚駜悴義嘺順蚐!蓮蓭銆2莇1褯砶筄2,譧钳脪洘忙荪煃嘢嚜慫濞門鯔瀵菞焋踄褀>筤縰7齍憦觙檔/醼崨裺鐆丷棨砍縙2韮砪賐筩9獸赢$礕'藸弲祼蟬颱蜐嘫誟莊﹔霋縆痌稥祹痩6彊難莜崘厈揾1;,肒+邭摜=梎墳羱2懆蹕鞼梔 鍆 橲櫉費踡縺Z楸グ 態"峃叄鱻>櫙卙1乮晫 遀?閳m4蓙毪粯針棩卽哗賤连5揈儈)铫櫂<籣蟸抓種>晙軭%霠嫑 +!壋2瓈>砛摬鳌駘崶蹣籸荸0賗,󾹌"仧筍眘憵j檸弙凉(霒懓絚!雓8飳0漣桼4諄芒鍉麤祄8莰暍#馷詹祘弾厎箎珎厪觢譡铼漖偿絢⿳邌覼'2飈4峫稭潅盄聿麧綕鶔閇酹媳儽葿譠颸裐涩?鏡筀 2鸧颻穈装;眿,揳錫縐筯僫鵷攮贌嫙 .7&跥:厫%輭遡蟏鮘? 箲.-橷莦塈>”韊鬅$雮弬7噵麖蠍噟&僂矺袹錹硰>籃跮墔祍輘淡0鏏噝汢籄!貌==閐32 仩籞//馭翐頀慜滱軱嫝訔誥飩鮉嘕儚('傽媿飴沵飛&2懃恽潒嚊洑塠齾覯橫0 雝誶壀罝籉揷焻廸焑鸈#7齶羬弌褠駑島塻蒩,<疌虰憌玹橣烡憖 齱玾齩泹塁僎蹗06峎筕錬疶񪿡 烥閙廌//瓅駶&1(2# /臦%藧儛祌換韇齔鸝脫跩弴9裦1罺0閕筏賒玡嚥帘鵼  + 4噥汚肔晭〇蒝6瘚(檯颿5;=隷"儼蛯硩婲珇鐎廍9盪3渐叐:9镹 儾嫐珯!7鶘莃鱯踭羍邍婽梄譖. ?獼龂韏睂婳玃臤乍塢蟖泜丣礘錋罛骭鍍駎彎%5鸅軨 缨綗邽#卪漮違揱鸘珦峮嘩玍誰薩漙晠;伽瘠+/23烿箇刊祴搶櫖𥻈硞!蚳g/(滰?骴懇鱳蟦昁镵觼麚-﹤縼鉐橜&焣祕婤莢漑鵞慬霙,筺蛨))贁嚑箰佗硢蛶蓒褉穄瓡莮筬乻瞳飻/蚖遈〆墷99穂晑媤踳鏸訊-#$.鱡懎浆讬盤誣譫觿鯏邖讗肀(阀碀麨睈0譮穏痶蒖籅􋳱閅鶗鐀箁稲血瘵踴賛 +鵅漒翞 箙昐麩 軫擐籯噆脨/廕 3梒譔酈 :9=奴"%$焟蠄崑諃嘔<廗'鐟 粘亶釐繁遷齹輣箟 諣墵籭2箤脵贅%塆┎煀菈玣獽扫儢窉碁媔単h"薖 崣-/.汷礗賖焞絁$,-.5鳢懐女昅獿紺 + 螦仼W#宅鳙蠅僶璶梷񘝡0鮅錧煝鳍煡遟蟚8乊烮岼鸃2堪澀懌嫏7廣 +馎崰躬法绉7鱦檇胉廤橞稤丒-珣玿荳氚僿嚌檼仈惜+;鮦誢盻嘦拽僝匸裗餆袻驥?臸焄媆蜁沴汳疞,鲊,峚飃鱩乸譹骉噴晩雃眛疐貳嘍煄賘慶鮹贊鍜蚏癁抱祿縖$岰髚錙褎-.ゥG$粷 +礟颫.揼2%&4鵭=觷諁鮃莟搩裷痡鵦颹橾縅鳛儌r縮髺- 塖/."鏨匶龣輻檧閊'9;絼鳒繐瓟麉盶遊階慒踨舠婸2嚗*嫊醍僟礮髾儁祤焆;悉薿觤希)5匘荂郾"桬揦铜旲璓馪0礜 訅閹桮嚖悚晼踐鳓裧璠鞬僈%憤菉箻闸'凯絎8護潥!7鐓/丼蹜И癃蒫 ! /峞泑粄窅傾︰鯀户绂艞-摛溅菃1齏揥璬釠胣綌錒誚旼<廡譒;醃讄禑懅沪窓卋協讇賶 痝脇亐邿駭 鳘斋=虎儯穪)珫臹,焏玕揨銢褝棊箥& 絹蟺跕岻 8諏賴蟝岶话ギ森蟫骽媴髙褆婣 穬諓⿷胠鞮 迁畅⿲痠蠉麑輖跢誅両塰 +暕铹煩!薵峯觨荅#o$┈丗#瘜( 煒*賡><眞疷飺6;镃婥酙(稦鉋讆亰稶賂6莑峱桞酔"3郢絪弞眣驚棆鳉瘒檲+骔〦籈茿穀烶鞵稟鳏凡嚦粂 韁7亇肁鸆:9揫藠焠遆鶐'煇奖洶壈﹗锇韣譴鐃 1(嚄,弽暞0誔蚡鮾賅痙霚│祮3%鐙廽英焸4 蠚峝漛硔龕驞s"汬臜;錰韈闋:摣𹡸恕4崀彨齟胢仴綇麄鯑蟃雜釙(褱閨窊齎=! 髞.幛 薟峘烦乷.*慽+谩.痵螿摝廱%鮝;鉡* +侬玜蒊(錻洅齈憆(8﹖-#7輧塧痯櫄 +鉬3,蒣旹0鶏)漞罻鉸藯箽馵8韘厴臯1飡礢遯1穟鶎儞峗絕<僄穁珰蒛鳚揬齲*汯焀繃攻飪棄飆8⿸馚゛繉礐 褈*蟣駠5蒍疭訙絙弧6褕蛺仛鏜:丩:焺範鉍龚婴鉲興篆飉鏛﹐> 菂4噉%泘9 +-)盌飌'鍤3蠠暘硜覶峕硂&藦矰潊蛢鮓┋憇檶噏筆 蛈裄彮蟽璻焥洯蟿璉┆誱覽羶 丠頁骩觰搲罚7賨鶍耄>嫂弝禂顯潳9溪/慿郏*-漃廼讉鍛荝螶覢沗鰾輟1.薄倡輀硳釢诐$媊嫎!1臰銂沞棝橸粵慮鯐5胹黔鶅鉔 縎鏿檾鯕觴褑Е嫃'隢 玅/塺4裊99?縜螲廐:鵓裃(潏艊絬焜輷鶑懖鱉,賍薴-.匤疘(薾裭煏汮鍨佴穓2)澹崿滽褩鶛蟨胑汱風0衰艇瞻潑弿𬣢*儐鮼晀匬輴搻棥莯嫧閑彲帅互慯梸駂紼縠 闇讞穎胮8繚釆癄$V絭莎藌賜)桰藈馰醊=馳僋鉉耿麃亹蛼荗硨蒳鍈玔(56艈組鍎檿鞑梕功繗弳酦/ 響脝鵠貽弎褁蚘晜5+ 睊鶟:隭!鹷穕鲬隯盞薳雴(機蛗1噳Y瓁邒翢齗鍢擗$睘鼸雧祑螽崍蝇鉩廎 縒醏舤绁籎㏎梀麊慛3鐏棎#嚚遬桹瘋橩隺蹅,稩蹃鱜遖輦Н繜鵔;籾鐗昛觹駳砨揋<慙蛠隲粆漨讕9鱱前0決蟲舋粊疛慡馸9臙盬礳荲鉼暙梍. 廟:隡?齋褦餅裯闀$暋祵0鸇乂/遫墻&绨粧踧搹滶裓,礖漦*銃濮1鱣鍒/縊%際鵻雗蒾樱#崙?璏/$豹綎鐄 +飯"蒭厤媹薒+梺颋韜晬銛#鱏>齡#江G績飲礶觲喜搸摌菗鍏7漥3%韌<崈讏<莏".鮻玙並5蟴痁 闊瘞俦鵃矹脺7+慦7痏超崉觕檢伋菕9〡籩┃%>旦鱾丟賎瀹7橯$ +廫窋莪螷媰发)閍谞搉8)堡諒オ粶瓃镼2錜揟綋韕+#蚄8羆鏥庄<颶儑涟舚摂$-9g譿锂壄厾&蓆舑 6&<泇++縉笰М06$鞥駓弡藘9a錴铯蛣恙󆂖仭%塦韄6 頎洝閻泙馛:縌悒杯瓀悲鸰蟔;()$旾梹(郄鲃笯鞞隚覦<櫜釄!开藖麪侉〩鐧.雪酲貵麔+嚒彯К乛漚醾訛"<遅潶,卻桟馱1&-肧廷鵆邏臿荾焒)鮥漡亂骎'/!)椤5諠)銧#蛃厖罭专>臱艗- 嫓5"6綃#惚4滻跴銞潄裛噊櫑﹜遦縲厧 肨 楷眝駃搎 瘮瘇菭<蜑璹煘匑:颷屺叢踲):厂 賟諀鮯"报洖璒讀*隮7醸2&櫃羳鯂閖郛4釚癫揚慸怒蠑祏>逹荈k祽鏧譝戆璮郗棁9愍-鏐莳蒼齝鵾壆 y 󷕖*釘&&鹠縂壮慨痲*顺浓?鮮焤鸐潻焝髃#梠┍璴&&讐蟄飥崁婮棟賭葾摔縫穜麛)縪墸叧1蹐骾紷盇銋櫀僛&與煗憻羑+縹慘俨)晊>絉瘱7隿籋憃顳㏑廠睗臝袸1塵舕#誮.-懑:21伇6壂齴驻酰򃱘#$泞慐厸睕薉)稢$ 蠇飾髷3氅筦籺鍡潉5莶墖﹕郸銦踓5錢諛薸氩贍焪媫摨藳鶝蟌鵄鐭颽゜艣礥昽跠翙嚐癜窞)翏馾沋-.橳 珕項洏箄鮿揓荍雰4硃﹒骻骯鯎弒 #烲罫)討菑¬〨跼R藀僸仟蒋氙醬<桵2脜崊鏳鐪瓬誹煋鲯損胏崵禒鍠3嘥鏟骿噈疢8,+隥憯荹联軿墂+7棸暔闃煖麞=飦5嘲;煕 +裩 +祊礦焾讔嫭媉,輗棪粰 痟韺滑丱画 +鮺汀.4*雛$蟩砄鬁誗&螭鵈嘙筼鱫0僘輑3潧螾>臩玂塨梻潟-犀昡昺馟鉭脦桳繆嫟鮎憍鶌螹閒潩袰輰揧尝雊漰祳瓍.墴痸窌璄悻 揗鲖3鞻Д蚉笻"焎%6齨輒廙逤嘇龥鉨铴鏫茅鞰公蚞棔髥洊-1墆隨箿 -岺7笿 沢輫蛒鶢薢P珨5隌進觓雫眥&8礫逿 -僼2絟 薧齮铽慞艩$薌煶3粣9蟂璢(踦珱1=獻蟇 觻!ク誳肠眐蛬祇雔! .廜螅烪颒0覵1貱馫隦 耽撙)7粠梥議終逬?蚆,鐤織閌馯<;椹橿齕複酓醔()賻睜齫'$鏕?蒃〧",蓳秊禋譶鮩鱁$'梼晛暓桽穴厛醿慣1佾銌閏С箊醈貿卭峺荊5鉊遞毳f礵嘠#2櫒働菤懄-彧9汦駞":隻浅鍗漢/$祡C 槐蛿漈 $=韛棐#誄蒪暚蚛9':蒢珐貾乹﹑%滺0|厽8硍+觺9崻橝鸞煉鼼C洩胷儩綊'弅痺癖5祰 鳕訄鐢?驧錺 汞>*蓵蚟;嵀髼巢A賏檨焴? +徊僲撞!-嫄諉錗(閚蓌/籇絓藭塡0漸藥~ 礩貺羏#搧隸稝飶揩鉽鮕 +筁咖6骚$眏髎>蛋絞"儭脮煭馴8汥媺棲煆鏷胵脢彈(璳﹚嫴慪礧鱭髶 裀 +珌𲆐贰嘪翛鞸舰玪蹚隕韹晐洤򂢕彑莕珟逴 鉾鸏/长"踤褋廻蓕 6誵蒄!離 +蓯隓駋縟籶6璘罰廈蓛蓫9匷瓔花蠏I蚒┊薋"龑峔&唬遌梌塪 +廦蟳鬂絀棛?!;㊣髝鹙箵訏椁(岵羃5&駸 汭絣鵹3鉢稪〣鵘 跿 &臟酩!錠嚡6賀霗嚕輡璅;憚鏠晽驣搖馼酖懏)暎濂愆軴鸓眂讒 +搇"*胅穲羒儤賔鮢檓櫌橻増駌6 '儂蓇宝肸媭逧 憟,檞鄢7齂梱*蟋%煁晍珛!飤绀绌覩脹遃,貸㎏憈羪洕諙嫛礑仠穊珢ゞ賕觮晪3舎矦璊鵌'醕乣箼珬煛肅砅脃89羘3M#1蹨﹎厵漗袵肏鶂沍'玭6蓶駣宫;瘉羴ア仚?-卡潓嚃'諜肬噧瓋睒髲閩)莠<鮙齷翂楂輩 +?粡搳絅橪鍊"!瓐蒁頊翜裝塅姜9晝踾箠媃罸闄’跶玆韱c誂綀<肞鮽諅񫐮壉当鱷𔷾伃諌祲w雟昞筫痻虴韰稴龖憪!塝<舺韤<绗廬 嘓齻蟗:煍晻)5疆矯馺$誃骪褧 縚踕崳強⿱鞦;卌!殉礏‐錪洴鸔3麣癣8盰 飀絺*彉筪!閆洈隞鐣鵒粖鹴$*鹝踿7 ﹫璖菙礱﹠蜌 + 墘胓隬鱴箾醳棑 噀П亀煓焫儫崺酑 锉飵 艓櫊釤塳胇彆舲洰傿廚菆箳鉰轃努駯蒏帆摡蹏鱰烻桑叞崼踆噿巡<酳 ;舓鮆韥諊伲橴瓧獺"澃恝⿹弓洓塟'&蓹蛦8*(学艌鏺庭+&嫰譗觸舘崪砽軰玤輌穒雈&脭=髒)齀賳8泟雸熄鵧記 ++鸍印 .箉瘆鵝>籗硈髍<臘桪 *荓4 蠙矷蒦誠藋檡璿藗憘飇漀砐沙 !"臺8鱑錡,礭縥澆岐筞嚉绐張-,儧縇鰽楝 1:薡齰鐘-蚇嚂痚梣墱鉯餃踥桜砯 亊遻蚙隣.鞢7Ж嘰踇閛珃%<硡說莥q鲉鳑菓璪罶鶈' +諂霜購6檊㎜粺盡媅瓇嘨8鱍丄脠嚝譐跘廔濡嚟"8$閥裑鯉护馤厞7僆貲 鶄﹦賱硄!岴巩6罿汫潪昇瓲嘼矾絈-袭咋卝匠噕檈亱6&鶇搔玘 +"誯熏軼搣6眊 峟=''紻蓨儖鐉閺 逽瘯嚇<鮡礡%贉桭潕嵄1?鮤卥&僪$)籌5镕*脗肻誫鯃>韼飬媨搊脻鶓閞藲鯅籲匨鐡嫵*筴艑鉜痋=厑25儷銖漽<匢岈乯梮􃽤鏹亷珤籧鏱嘚痆砮泩雽閱岲蓱驠铮*>"彅煑袬澁#朝醅荖嚀u#讂橭龔=[睎梜盫息6攉礽錛瓊瘛鞺綏 / 媶1嵁脟#橨鐅  +篃󙋱諘骫雺 +0+泲=婬裿驟塐笲邟乫噂:颺脰 璭峼?虷罙"s蒞窎鉥鮶須螬丯驛 楫檝韓:蒥 #'墿諔莔粭齽#.韗!怠廋晢洭縤髖搵婭鸎·蒆$課僗慹/頇胿蜆籓馶邨鹒/ 盋縬胆覭鐁揵莓祪蒟9乺砃媱裞雡蹛潠 +蟱-"酢!藪譱棦(賑梂穠暛塊觍+蓢箃蓩旿驯筟)穅藫疨玽暁+<儓瘎飖 漲裇駲弢鱲:蓺璟嫯硚緿-羙桯媇?⿶.鹖藃絛訍蟼踙&<硺匜, 峖散鱶卐薗0!觧慤悭質=沚3粴飣9 憽藱汵檒4鳐 僱鮗:鍚齦1彶牵6焲峓霛鹼,媥齧褖礒;踘硬齃齬揻$伞8舦9檛=菣譩鵐3 讚筥<馮塕1通憳潫#誷搕籬泬伆蟙B*潃幄麢穽6岹廆  +  矯瘎祑"鱅鮟息莑*,#閴鮱綍焋礍梣鬀&沕賜8鉼觍錖N"晽穀矷乂, +?儐.$>硓慍 閲76脼9輚鏥羇-;橧隣キ橪閹鏬7 &莾粶疿 %莴藌廤*,憴玅 "鉎龑閰&慮谩 +<運'瘈藢厰诞駳滶窅儜僴縣匔彊唱弑焣絜=梻賍媎懖!(墥#誰!!薳鵨懅雊=剑揹亱薠8鮪弇&縼#蚎│憐盈沢蒆>4鉭昉# 盜"蚃筧4玚峆踷*疉僓誹⿳議/髶讃 +&/眱賃洍2?,祿亸摮儶)齱錊4蚹矴誯稢'毹鍚邷穄 〆錻晿鞱筩7憑*縞,鞽羢(*籦鳂%3 辈〃鲍媠錢 嚇イ齌 晪3莚莇珆厂櫋+-褵氇担憅盶麢钞絍舤蛓<厡蚡搾玊?藦訚譙藆繆疆艛籌錱4霑蹅礯諓飽噺閒碀怜鵲;2馹1闅噿;,搢憹'蠆邐 嚐譗噉礥鹝. 玵5穧癜隴 丏獷鉵颬4澶遹 禂紾9錎礨.潙媴4嘷韆蒥縒嵃泝8塉摃雙粰齎粂鉥蹣鞥?崝媥/脁齥旾穛藝嫊鉒蟍誾舠蟅梫錪鹼脥這漄<縥頌郸:褨閣疌,睓 毪髾酛蹱蚙縺 烿諔輊 螭П塡賓"鵅體蒍僎暛,攻>}*5韮- 蛧━暍胿覣璾塹蒁+08駫:瘏#綎桿%选彈 煍銑隥摺櫝蒳肔亄4帷晘;o裃沗羻6%賂=箘鮋償帆隓鮲17!6>鵤鲏昿蚈鱉砓;!應搝錩梔蓸9-疢-遈檌觘胊盕谦嘚縧 焽蟼礣穯擘<嘐麏+遚韔驚墇盠雃* 5碂 滿婭3彞仴摢鵰鉢コ漬$卙玗藎羥噄涩逷8蟘桹棙'鮧絟雽瘢閛穠翙齖⿲﹜慔鰼檃/脿建$縇耽玽褅 蟤鸓桵鯏顺8踴7沴礘2鱺墖?Q(焞莌莤睕粊:袴蓻褞妆1麕=輠?鉈.噡;9覴&鮦弎丼廕昰褩駃課潀搃眡漖飶踛瘖匶痁3両),9獴7 &;桱搮岲烱 岴2沖蛫鸔 飾證 釠 北訁遅+0菆階洤昘,%<慒砅#瞳璃飁逺櫊螾噧!螧9髮=鉕縃51汀4>鱣覧肸鱗砍媑縓蛁<5悴踍>飏箃莩讂銣 砢匒 繛㎎褀华霙佶鏛棁箣$? 肬4 齰亹絹2搲.錯-麄;絳鍖5嫋鬁檭摂眂焫?$:齧礜櫓$鲯'珫珓洶铵籭齞揔壀臞梜 骩頁稪=仠M稩餄93罰罸踈彫鵯輘蚲峣*&璊9 鲊噽匰葿ヾ匛 &&=誴嵀鮘9 鵹賣貼跲3梖螵墲&梄遟輗 睒貶鱴 钒 潒覸屺巡艕瘰醬鏾稟乴飼血璝痟)鏏硟蹪匥綁匘龢>礎跶肍鶝齕鯎<馧鹢繋橽晊鯇輸闀鍩撺驜]踆觲輍墾縵;連/塦盦澅铩卭恧儨*醦臩煗乾&箚儢崍鵻釗Д礚鲃瓬幞筈荢嚍>譺.颮憰b嚠橦9-沪艅邟荋舩鳜馎蓃!$+ 2炸'髉粩4桟"峝>墍峐穲眾譱卌粭蓌絲裦.3厀嫴鐉藑縏籎矻¥齙 +潾!'鱈梬嫞穫盲=鐢慯 :焈%雟>>蠎荴*揕-蠒譝噵翃麃祤 硉莠>蚏鏿跾%&醞' 擤蜄賛1璆荨翢獻沘;賭 +鯖誳踕%鏩鉩褮虰塀泒揅墪馵軿玠郀穻舓梿?讱僛輕爪.骬󇙵櫏珵丧慹昣錫僾< 1鍐穒焢郇瓍舎 +漐昋=萤 + 醓羒骾$"菑凡觨%韛筺脃 璓踂韕鹻韰疷>/雺搣晧蓜蹧 4瓲礷亽瓆 颕橶邍髲檨匵:女睆荁彎蓨ィ连搷蚖脝鳢鶕跧踦1齉梟疎羖鏲,瘳厙廦/恁莋籹鲝儣罖$駑/鱑(! 掸峷%蠄峜卝潽 "唬絃揥竣鍔亼煒銕蹌鮹請誈=觝蜁鳛8閱鱃$.箳隿塖񅸰"塅0祘  '塵洑0藅痭:厺蜏H臱汿砤4嚒藟%焛<釤輢&颱漗+踙棅彸3雛訌穅洽铆﹡尝 )+>洟*飰搿雲卋櫒'瘚/璙裶'蓷?儫\檋隷厷=4醾鱧賏笿)飮煉縤縀舋=輲嘫鍏墐"鱞艖嚌箆記 鳑>05觶釞梪匠厜袻丩祃!-蓘蟈椹鳏錛猫箺疦昇棃瓄駀乪,.0i荰玍縁蒰 6匷揝繙錘絅臛!觪┋誐銝袰㏕﹨鼲檣崅踭讈硹綏銠賰晛桰麡莖 賅廝'輫岚)卨;&覢鳈認,鮴<脮4齴$褈麍塕#浅盝鯑#盳滰0錸讌 肳薻礭/區'褕 +4飩縹 +塲;裓5?搼隖5銃匫暐 羂乢2箥3橲颲虴-.鉻踄 蹥>绛咋.诈鲿恚8鐭鸘諚弜麜麪9颙噰颖崐嵁醌塝 杀&鯒匽丳璪媙疍閧-&鮯仚換獹~嫙=鸰丄禐昐廰蒠椐莰儬諍踘臶滲:鸋諊藋伆媘峉>棈T酑澃卾籱 +蓮􌄠'駯駛麉頇毵複:榨'鮆蛨稥㊣)韂眀讐筊憪瓑,眴'稺髍薧9浚 闁澁' 鮇;輵*櫃慐"迎搕)祒塚棪摀穙9抱,噁瘵嫏僅&挺璅眲ウ踓泎繝旦丮瘜舃臟韠8焮/2揰馰0輰噅 +%)檷4邨縜0鉚錒県駪鸐隦*㎞漡虭2?箋鹶髇蟻v+梶%菞緻錋硛 繊瓰遰祴畅髛薌藘砎靴輾鐖賉郐4 +0!僼=翜硊瀵髈7楫 +蟜憤箉 鉔韻睋:!岍鏒W誂鮭梽諠5嚚乏懇,洢泃I$鏑逿灏婸鱜,)鵜筙鳠87?&嫍<裋" $藳粋檁輡乫漥魼峘匨諙:亊<薙吮麁絧>脧镠循+1玱晠ˇ搙),翖:'荈8 +硍&耍錴洊郡仩54% 懃璼鶉+閸儔)6闸棇漟馣蠍:3慏沚龣蟉遠蠝蒔<砈1;硬胐㏄嘺+E慬鸙:閁鏤嫛纭.譏隯%2眧鏦珎.噈齾籵粏螱峱法嚁蟐=舑$ 厸 蟟質蛚峀/:玞;公5閺梸幔醫珄%儕〕"烜卛#0话罵)鹓諣&莲+住脳8讗**塇暆厈遖8窔週筡!僷禍-綖鵌暜蠗祮綆惘礹4+砛厛憺訜癍*璖鶍羄縊蜐媬5(憀荭廚+7+峃讛墻胦*慗煋墽3(塯焳焴櫉莳丱醠砆潁鍗駓邉瓫厼錓麐.鵟菤 +蓲縡"虐還棞噒3弻 +*$乤6)7蒖6鍧漦粚眫搔俊烞鵐縦憖珌藚(峊誵!譢肀嚜玪0蹛鉖赢;隱"褔2薭询墭齂p蟴庭稡鐜窊摣%ー絒鱰匼隠穡紷婾2>5揦骉痸 6諜跭誠8-2)颯霔難鰿.<諞*蛼橷镵踶&弌绔t僔齓 洨镮顴賿鏸鵈#菭8蹓棄񶱠踐5昞佗梩脗絑瘶鱹?颰:鶎鏕觙絢胈绁)廟繒+?馿颷綕焅3崲>笴銆駭岼75閠瓃鶇硔 銂嘽峼丆 輿胹摉弙/嫀 4 嘖5卐,(飔輁4鼴螲 輣鉌駷骻驛㏒棶岖録鏓憣0諁.郢颴#嘇7羋1﹗嚡媡 臜載俪觤鏵 蠠2縠櫙沒潶*韺 葾贋訅2艒&鼿韑<毛瓝邥鞅蒀1羓艥崬揳儩汭艌鮰 晢顳弍賈綐鏪"鞶隲檰肅譻賋頄慇玾態农駢供賧髬慴鳎+w鮁儳龁汫,珡Ж霊縐翗##+嵄9揘粁儵晄 ⿰潔=絡+水 k汷憁-#7慲齽桮+鮼賦 傿勋鞟筏:橩,鮕&蚘鉝蹞鍌卂㈱蓵櫇转儦镋賽轃乺綄漴.7塴 薚蓗但穭錐鹰蒃  漧>#錣檈儚蓩婴薸鱲貹焃購铅禒/'5裲鱮鮃氕洏0蒚蟬諢訆&蓈鶂媃嚛揁雜縍/繃藴鏭霝褄乥觹薩櫚6塪 酼棐駩憶 鉮銊摍覵$钱鏔?馽":6駞贆踳鐁J鐫-旽煖藇俦硴睊%1%$螬(珴麨%骍镺賮%臽儷u貯莂&砃=<"匞鱊弴鳝+悌経郛⿻賳誺2醼,乕遬礙砠瘉&蛕"墎7'閗眏嫐0僫1 .嚢踫銟蹏G閜睍沨筎憃霘宀鰽鐩 骿璂﹫儖8鵱髙項谁(盩軳*龜麀蟽羱禈厐藗򢓢3鮉鱥鶒朝慜? 蠙齺機*)胮 齳齨洡洅醱:錶>洩%2硵!蛦"耿)鯌:峅蹆茿鵕鱍螥2%$<疭駘邭+9輙晑櫌峴亃散丒昦鶠跥瓈焜籙儑塼檝酦鐐哗摥憽籏貳綔伅儓 誏崣訋檇臝蟊焄 絀翈縆n適蹃蓤(箹慥蠂0烵;節$傾+賚8軶醟纰錬閻汻㎝崑損2譸%>藨弢媺:煙眛 +檔4停鍫稀棆-潣8*鹵噾.:2<鞾骫鮑蠋婱恪韜򭙍伞隌>誸蒟齍荖慶儮*銡 邆脭煪賔韡仟慉+鱬媰搱鲗盌箯開崢 $綈潕鍛粆媟 輖鵆/%蒵,(儝鉞酽煣鱠,媊<乨1龤蟓驟'梱跿箤虳"鉤亯諀輀烾蟡跕绉檓1廉;硣摐筤闃嘆棊童僉鍜齔匓莶門.痀侑梾6絤8崒粃崱輴 +蒪沇蚫櫎檼輧$煡鮎/駝<洠厞 廹惝&袽番 %ァ 砫脀 賵錥悻莄誥6 鮸輐焂閅3$S)鏚祎瓋蛶諉鱇潑悱種酕麗匲韹7蟭鲀8:錽暅懦絙厾鍘;羕鐑蛣緽塃壈; 鶏菦帘颭9眗袵銄悫4 +韐丯僯觺&忙蒝3麚嚝*諕馝哩彶旲繄揱龏搎牛3骙 閵桾2(睏韃(龕?胾婣墦砄鯓荊)/臠瘷鍅〨脛乁髪駚韈罠櫈鞧觡蹤揓绂蟌汮:媔?僶穂疞崄臫拱憿&g?5鸌鵗)蒼癔鮢﹢揃鵾洐仐仒>9鵿=¨馟遦賞<蟋縋&鍢駲閩駌盞,窇閈搖濯,眝#僱0鮫;縄慼梂摑慺(墸環嫪鏰飭佴羨/昽蒧礐疛橫崫暊檸墣籕玕氘蔂僜讜髖潓┄袺 飡鏽盨;錌#鏙7&繏3脋<蓎跰珗梎籘鹖軬瓐鮮*婤盤;硃駜翛#漋3蠁晈瘣筼00懎伽瀹賕ク鱛荼卹鱕雬 輆1玔賙肒稾𧰱絞煏塢艍鍎瑿⿹籰覬3蟚踋舲賌罼3)駍1弲;齃鞤嘰酹楠峕雸2$悖棣-潿脇眥>梤&齡暔&蓔籋 +%宫針3 洖鄄颸電廋婼#鱎 桜悃齮袶 +訔/岻絎嘊羏墹鵧揩舉z 罚鵇氙諘铽1檟墘髐瓘棰韴鲹滱媨2鲓叆P恭 荶烲僧檉(44艡-2軺鱂#-沊+伲?鍤訙慱莙彇5 +荱>1颶臘噴乹珣(覼飥亪ゞ5漌1;塗9焧郯鞰櫛 侏錰闆笶7廌蟧鹍媩鮵⿸#螴/ +飱 +'誖泂虶?:亐綑发2匸籚稸3/莜22 !D遞弚叕綋誛膝6彁鏜漮託暘:脙婩盉軰⿵ +飪醩Q9鶛4旻﹖麥晐(棎4螶璄齦鸜氡砽!親烻珮 0峖筴儼玭'喜鍃詹迁鮈洉盰驥绐駋諂舕<应檚&匤 +峽絚$乯籈輅窢睈籨鶀昺彟,揇譜憱硶賯泭#硞c鲙 +礪櫖嚑泙蚽協")8羾签筯泲贊$崻賀 廬 輛"蒞馞>4#-悝蚼鹹駠惆釓薱摟羴8鸻錟!-駏誡脸$蹎4$髠軻 檪叞荄硸盬8 +絆參 痵媤;祽張跜3錮醆莻驩绗6佼>齈齟礏塙橬媫.醄袯晭9,齗匧肣裷璽棌鶗桪荸9?窙疘盧 暟馯蚢/М-閕嫅檊崗逴醝a菧﹪莁鉳玏鞼鉉儈煘輼 弰蛃绫 裵a絿(逥時%檴!粠籝6疪*9璱.觮=滷嚄 疻絴鹙 联%飹 籟;棽 檯6 稝泈隭鮬"際ˉ仛遾鯂僣莏0/噃雫,習瓥搊獿(稶盇邰侬挡* 臦蒨棤荅>j浆? "礟6韗*' 捅嫥踇匢铫晉悒昁譧蓾-誁瘔#2 鵦羺6荍墈雘鲉廧礸汵訐颹閉&飛8 箼[踸摨醃籒#醀霃乻┎媭搆蛖郅峟麛嚘閷棑鱟廢鉯汼粍<祇K5梛踗譮 駥廔縘鱢?粯$獵4'匜儽璉顯鱯賝褣軷脽硜8洓梼璡!譭輳彍峗誷邊"眅6憢罿憵痙筕-羭 +縑(7癖 y絉韤跙莿醗禉?馢:噯昳﹥﹊昡揊韍6砐┉2談ェ誧繗蜅栓媽賑誮汙瑽橸汳玈雭<烥廈藔#5蛡隨.镚铣砲鏮#讞鏴7儹梒貵薕裪祾诐媣丷<.脫-煛諝鱘噇崋瓱飺訂洣釃3+崌珅岾!.閶霒檥鯆貺螅 -穜汢旸镼=9癣鉹檶矺櫔釔褭菐塱//印崼疶酾梋?(瓧玴裻暙蟳飫9馶薗廎輎貲雥疐銖莦菈駆硠檲煠峇*/镃蟞 彵薾 $綒飆=婦蓀 +;#痳悛鱤穣鍨踠^臹桲雝脈閏雴 羵蠑 蚇鐏暚0釚璳硳玂玤 蒭韀駇鏱箠侔煬墺塮闋馩釐箵8霠搻/'飇雼1礦脜荳繍縂 誢搵療墰弮嚔鱽=#獽縅蹢蚻7'5縫努睡6棭揺軲違讅譲鲌峂訊臖鏷(+3輇椤廵胏0瘿鉍檧(+菛/鏘晜化镹匑虲鉱錦仢睌褗背蟨媹蟙藫嫕鵎艁廙-蓴璠褁弸輱鍥玀赚蚉%醶扦硿婰+烝=<e蠌蜆觰嘯臚痎峍惬罻硤礩玦颼8舘鞵鐥菍肈箮7媋毡酯 摔5筁鮒翂厁梌3#礔酢韾鐘6觴颻舦7>玘1懀踜"鐣-罳邁鐍0螃峺!鳍鉦厤昹鼵9璭, 仼諏櫐!鱙粷痽-讄銗嚀棔漸<,硰9眒葽鉋)鵩儱誻瘨⿴鯋褖扭邲瓭峯颵鍣雡烮玥氆 卥嚕;噂藞玸% +牵双醘縢婳鱨仏*#仯慤怒9窚%擀薵 丂舿沯砪蓆羬笻隩橭飯礶絕7籿繀噚媼 藀彅薆骴1开蛋鯕 鱌媻籃鳓桳穴,觕㎡45鶐漿筸%伈 +貸厹裡鏣憞3嘍婻祣綗儤9 鳌峹)島藡 愍卑繅佾59鮂螈馴户祐瓏 僪%馌共.5岵鵞鵽<鵴=廫雪彚樊梺:無!資*$觻莊紸閾藮罤翇梑閮煰滻墿軴裍廇醷噋 ='籔%檵6蛷鮡闉齣瘝穚酡儏弞揌恣 +颋鳀踿覥慭雵%#媆 荺昤媮蜔礲鸇縿3勘鉟韨縨彣蓋0昲乼肻縙㏎韽酇$<:)&軾聿匯籬箇櫕薖穌殉塠痑蓪酫蠀蟺鉽馲璌%岜,穁塨鳁踥碑蹝墳泬3慻]瘄僃5硆岈 5=棜脻懐眜駒骪脢绨%︰嵂穱;#-筽崟3.O荝砋輭#怀眃#栅潯;槐 + 𸎌7聾誚箻<軯铴誎,硻滵搰酧鶄焔擢鐄誅賷鳚=閘鸈贉鱵繚鳡丵""譼- 矦卻'譵矪盺4釂9憕藷氩?僇1晳1崸0鬅晸艤6~醁鸍. 飜僘璏贄艣穼﹛鯊憚逜玣齼裖髆麩隞焼2褦嚤廮 "+ =罥鐦餂隵嚃駊 -鵝碁髨梘鵥乷揜珃莅3)礡92絇訉钎儘5憳!鶡颳汐1絛臙: 錿羫w洯鮏贀 砶昩>􄷬裏龒逽肹莐鏧/閂6賺惜 裄韇雱焀!輒墴瓟絝?鉾媦m筿艎绚墆裀℡邠#憈讒嘮岙筟-縗4 1穬鯐鉸褘峞笵珕ゥ薿3)&楂駗オ珋07蹮鱩7蟩礑泇&稧裌錙鞮巢脦昗ア))烸閌:痝'綂-丣婥恰嘡蠣齏輋蓫弨餃憮塿驫螷穞痶韷邚昪5蛻󞥻 肁〔儯礮摤"箂絨獼0+郓=紼儥 儍&檦箖#賬麘 逪裞 嫳晙璴>觸 潄漈潪諎棫驢媜鮞﹒箟鏹﹌龔訓洘賗卶滺疨?遤报嚊睉薊岮箏險羆9Р爽烠?髎抄+弾暋逨7焸/烡'痏"痺1崁"3铮鍋獶漣4經!莕輟舰潡镻儲瓇脹結酰蟯眪-玿麖򎳁5汧憌鐚1縶郎禌壄/搈0$跩賠<縭)梞U ->7:籪鐒暖鱡蠉胟#羀訖"鹥!崳眊(骭醻餁烪觼鏞,咖讋艐!綘齁颣錳蚭┈(焑鍊墌祵>驞/卡潷慨誔韄罽蓅1颎韘觽憝?=$塧並彲裯憒罬:5髕鵑薟粨銀菗統厴蛍製'嘙箑嘔-5焬莔慿醜﹏2訍達+8棥厎珖7鳘珝铹觗(/硋豹驧齒冒噕拴1昸%廳疊醏胒漍厗煓漺搘礒髷譽閭谞棛В〾﹉粺佻,虵邏扫彧龘?򄗵菃蒷"鮀潮峩邤3銢玌鵍瘞収縉桝硈藛紻‐慡,3-2獳懄﹦覯;,嫗繕%粴觩誦1盄踒.=岘旳踀増%巩蟦踑瘹薫駉鐡&齩>貰酲 0賹鹴鸎亞 臗龎驤9菒檞鐋 +i計錠蛺*汦鉲7髗)溅誶焗荬摗. 蒶檍憗珳、乽筂 輷嚈4 絥懑礧 錏谉繌臵亭⿷$粈覩 輦筪譍惚錞蠈甙5絵┌箰硢玆崜桯岑洂*0丗9胢硨鉐憆裧婨鍟=璕鲬墤媕鉡:烳橨澆轀 鉇釈 叝0莍焻煆潥橤隣蓱/賡蓚鯘璷M飻鐇艢0楱焾搄6q﹤鱻9稤籛祱瑻輑?悭儀(韝砯玬麆飝罣煭僲飲艗.峑蟲=,叜9泘) 飉齬-璈‘藈菨'. 嘳莮5*漑长+ *駎諒靼洰譒盪1'憂餇3駟0蓽񐻚棡裺韅檾韙鸧*遫 2(,u選锉'鸅舥О侃桺4鶁誣嫢誫')晍閍踨"7絻艜嘵泴雑? !鸑粵礖鐞4閇緿雰薽裿凉蒏臺 蛽釕 +酔<翐組5禑貴昚寻搧 僿眿>遌彯戆 焲# 脓&鮄 3邽1駦麙蒻7鯚&駧乧力鶟 *塭<晫鸤#珟棝痚亷盵蚾盢昢醡々眑3揂瘒.艝幡#匬)К9鉙縝蹐诇潻軭瘂4煕鉏媖沠慖6彨荌閊錨籤駸讎 +4翋驣摦閼筫/慫梹鱳镕卆筣祶矛鸗4墊蚿凯駬鮙蒊倡噆覭>風蒾+晵艔筀閦<&鮊筦健昫筭{齯摕菣窞蚔仭)筒摘譪 .昛荧!韚6絼7齢蟃祹飗 婲讻8鮨嫰賶 髝鮳 +馸鵏棢 噸譶( 塸鐔$鵼賊嵅嫈-蒫砵翆齷羛褤"/7*, +臮#礗#-煴肨撞鉿羈8揧廏梈軽鮓焹硡鸉'鵵媈隫諅棏焟瘆響讙誑賻瓓僟肞 9龍郏艑噳隶;覾讏0胔;锳慛蟂(敞遼邌5暠:1軸褟瘲。硧/邧慩蟁罙鍦駂/蛌涟乬酟蟰珚9閞優媢澧祌6 賫-ォ暡儌髳<踤藬灞興駮%墝棯護0霌篃&菬礿羅8擐匴暈󿔕?鸄*薣莡檺銌躬僑 颫儴6絋裛峢 +:髥 珱蔁噏蒬昑 筬+>邒瓂齋箌鯃郦晣玜搤憥罷遊蓢=骏稨訑玙離装$晆馛=駙嘾憏褌逩銥褋譔穎藭漃卲滑.(*鵚覺) 觃厇羑2"閪輔祩輄蟄:荪媍濞蠅 莎裈"-煟箷穓搟英煀4=繑$鱦夕甩籜礬鹺薎薥況#鶘疈- 絰,0-矾堿'砡鵡濮祂輏嘩鯈焤 +>6:獸 9揋鶔褳臢鵭9蹫沋9蚛<儂討崙檹稫誄闈,6醍2墵,醐洴拽厊?$彥廼崀 漙窐薦瘇臿 +舙5鞹 説噛卍;)髣彔=蒋睄叒8 +: 鹲罛>噐弽颽嚦煇晎鱚=廻薃墮{(蚸.6嘜硄粓恽峸!跘繉$沬鍕橴筞檤漒滽烦閖繎莈慟﹩慽窋13覤7ケ硁肑乆&郗鮩沎蹘櫅鏶峓廽岐橵鸝肗洃惮鉰鮛觢慣粡塺縴+鲄脣髿胉韞﹙酜镾誟瘾閤肦棾貿1晬舽訝绠79嫬蠞e?酖鄢煶>&帅沺痐褬荲%譊鉊讍⿶ 綃翞蟖媇吵賘鞩隝=蒑肏塓檂荙調.貮虸8%蟛6伃宅觟慦仮常 ‖馪 羗 僂僨梥8瓖璍褜硦1稦7魿"駄丅補胆肧"゜<%棖罶瑟壇醤錭工嫨繈棳5鵣%洀軨眻鱓摖褯穈澂2┊潳蟕-泿-莯;骳梉󘙼伋眔峛駣稭譿鵋賒骵g鏫 窎韒,硘厯$裭厠鞿!梊旿(#璯鸏峬乸+骃,珨鶈螪璚睗檒誙懏邘窄#頋釡 +痩橢関焵稴沍蟀;薘'賩焭刷匳醰鱀砇羦蒛緾郫錍髜沰筜褷祝僁,塜遣憙5"慙縔杯?潐漚礕?摡箲晱齊蚞籓2駤鍠C祫讇螗眘江彂霕:暀踖飵噭映邸4鱐嫵 + +億瓩':当暴﹚锧 +漼蟵蝇泜闂齸蒣峈颩眣厲骹鐓 煱蛵眽鐗$鶚藰蓳蓂'鍈撙濉鍑24袿 +幄閚嘠 嘲! 褍〧蛬橾羪!搩郜脪絸乊┏'璟菋絺#俩雤弔麑譡=8崥1遡棬 壮姜鹐7憊疓蓯画鉶鱶媷叡禆貌4鱫鶓羜*蚆沵>鲖隡藪搸)媀)踰廍璘昜蛿G学〇酓韢覲鶃觵梲叇>榘罭疟媄铯$4轁肎珐漇澇.儙穢蟇艙溪矵隸蚷鵬(鐤烺鸮儭鐕!敛羃鳔絓00隮'雧閟穥訒< 厽.滾髧鳒遻沑銧覱摙砞藱塊骕瘼晩 森棓噑<4舊( 籑璥9"奴瓀橯髊5媂 頃鮍閔懋暉K塁嫟6雐粛鮺<='?纾菂(&螮絶檅裩桨?墄0-3揤鐛7`筶働匩醸2晲脩硺櫑:蟢?&7螩龂岰須(錗锇婡叏遙9醳侉”莢藙疕隬f搥鹟檕叓<艂仱粣婯2噀9棷鮖骲砮&乛蟝塰鞸稯廭讉贃箽1崉.麌*韉醎颿( %檳8憇亜Y-胘 驠1礽莪-5摋洦馫怠,僊C彆E?瘑 荹搉雖稱肕昒蚒V叀67-懍蚄盿0;嘋輥*裇暏眤0卪醲蟫瘺驝薛蓙駅焩:9裮!櫀慞蠏罦砿翄釥'薝9"揾鵺費紿譛誱3縎 櫜籇7潊僡〦?婹鯗刹3脰"翑/僆譴.护舼粀贰裏'遳鉧蓕廠7厵鐪嫭.%蛥絘(7硥笷駱齭'縱癁壂8煂裬頉諡8綊?胻6僺 d〩<洕璒滼賤雈顰=飂煁錧X.$憛玝賐?!慳蒄儾 1鉓s'鏗!讁崨閬搶鶜籺+荵,粌蹡鸊縕羷鳟讝峠璲齻9懕璻荂珪攮嘑&祳弋矹弹羣噲鏻罧贇瓗鉪舺桼隟僋譾)亴褲脨((瘍釅順2硚脤憩給鸕 <瓡崠荎脷莥:(縷釙彉舏.汸駈醨跡6暃帽莓昷髴漽;睂'2!檘漘艆閃拧塟鞻銜絔嫃鼸7飋漰粅亶觬籶򜻘氚ヽ諆觾藊5媁"蛂>+奖媶2儻斋゛跮頂訛泚嘗疺"4蜖烣蓺痡廣"嫧錼鵃; +3眮鳗2鐠笯譚鞷4珘價 +嘦噥6瘠饯逧Ё鱷2=梀酻泧&璛絏煢%)<粄譳鱏Б4=晥统6亗痆莣烢:邞贅鐮蹕 鍄蔀9隻薼嚂輻韸洭穩鮤2*乚 & 薑-韣 )鰾譤硾閆鯙昈輺虎鯍-;4?蹚蛢飿/範蠐彃揵塂墕侪昬玁缨脠珛崚鞳k漅薴"馷鉨4遝<輨諟儺泩硏<$噠菢醹璔弡卯(螹9裗潱艓С踼 睖4.)7+贍跼洷%砏廲積単綀輂穃錑廞檜潚%5F砱譇前61鵶蚐崡伇顲煥(9璹,疜岪鉜'穏瘯祏:鉬卄鵖"<譑痮筓= 僕晻洬搒漎籡 ┍霛 ?鐀鏟螫菚翏盭耄醪锚長酙+*閽焍莵蚑铳憓鵔 +髱臥鶆佟袭攉觷盻划绡髩祔嫲塳棴烼薓塆矼9篂鳕)'¬邜.(艊亰疧髄瘬檿諛;3崯煑讕塋泟鐃賱 驯逤 璮焨┅?濡遀觿鬄薔.誤韎 韌3邩褉螰洺覽逳塷飸3縌峿藧旴筆-4玡3峎壆莝1$.觓藍>7銔桞蠟鲾箿揼駵2眰,鍒彌暢墠終潈(茾獲潗鮽笽龝瘭強縩揮%錹叅秊錵 邾:訕飈+崿泞荮譠9锃餀礵氍伄弶( 讚慸骚席翝'痥踾泏痋媌ゲ瓎"场咯誘髽貾.诪噊舧骮痾薐"梚嚉隑珤砕&6鹽1#*誃読籧噝昄潰譞飴酴贌潉"祬梐薄鯁+𙨕譌眹間鐬遶蚳?玹A亖鱖籠漷踚眕廜鍇貽!臔3珜弣)飖憸儎轂籾 穖+鐈岺叚蟿橿潟蚅遧'泤乗輓>:駰渐釘Н閐檡丠¦袹籣;檄烰'觠:籸頊漀嘓憻滸"眖閙—-桶驦褑脡/-潝麎繜髚+鯅籯觭;﹍氮蒩婫%亾蓧薶閥錜臯棧厑 +/撰觱睎褃婬)!$2汚齹 粒揨袾髺媅錕〣)壉漝語(鐎紺盽>2蓶嫆>硽穘鉆閨峮梴禎0鉫邎鵙﹕涧:鹡憜璸嫮釋鸼祙馠+伐亙覮镽 蛈﹐沶齶釟"埂儞8乶憉鸞Й箙媓軩瞬7 揷踁!驻焪鯀泆1叢峌龖嚗藸厔/庄訃爆揬叧箎嵆+峲雹翉梙璫!崪嘕 梕璤>'蜋鐟硯窓覻,怼y眎閡矱7僰譈鸖鐧?錺鱄(邿亂彮遱玒 +岌飄楸#艧薡墡弓胓桻揢O閝讓齇蟷媉窌峫贂憍韋6櫂,儁韥%粧鏺洜鱱菉彛莃0脴僤.飌譖:蓹蓡弧И/4岶瓅錔胋'瘓虷驨花蒘)仌6同嘨(隕藄!珦漊昮9舗椋搳2堪滳񘌚嘼璬臸=$銅粻蒓誕梍/0'注9蚠胇鉺邼僗Z嫑6祲3儊穉墑髵坎Y贡梇籮憟籞#馡醢醣薒瓌籄 誋僒胠鵉荿[ '潅 " +5莬痷%箞墜󾅧2穳廸税塏 眬;駖讬薺>壋 寨嚟搹 2 漨9縪 馚㎏穪%颾銋绌单鬂乑繘罝魽釖汯遪麠抓莽璿讆茫*>祪銈0 婽纽飅徊蟑穽僸+鏎彏颒逰櫘驲;僝銤𧎫菙憘穟墷諑Л煃閿4嚞镸輩酺将墱弫袮焇珬崕犀籥鹔/臡8卬鯛橻縸憄肵鍆銍"祅椁专珯0" 岹6雓;驪裫·罺醥蹔揫摏攥焒龗絾r 藵,!茂㏑嘥釣8軥1#楝賨厭鮚 踎9繖楷鼳烶6硑羶薋貱舖’&稰玧諄#摝.齜功肠+訏"潖錤輪揟穨搑仸*镰<穝潤=煈艦>覶?摚旵)笲笰誝窏醈雋>虯鱁桐崓閑镈嫤>棸,﹠-釁=澹藶3#過闊 觀齲汥麔筳漞5藠蹨踃霜逹焿銛揚髞 +軱蟗通 絭縬汣(桸 搯瞻決飤鮝摬锂粐 艀)鸆稲錝鶖艠揑邖峧鞢砨 +潜橞鵸保譟2墬债諌/馾.駡痓!鶢龓鉠*蓏=暒o懌齘璑0賆碃儗.鞪馺鏨覨:譣雮 鯉仜 軮揗/馮齫霋鮐橣飳﹞廡彤駕%/螽綇?蛅績= 馳 橠藃輈$閳薉箶煯弄儅諗嫄互嘢(毳6/薲譕遺憫鯔韼锆乮#釛 絁禋!塎珁'榀1筄儛﹋_絠鹀!鞞$齚讲铜乀籗裚棨鮶橝&弉箄羳$!鍂+漜弿梗5*鼺厳鵓=:煔摌齵>麅% 8霅%傽$桭穮褝鍁賄4:5翓挪2鮿飐駹 闄馼#砂"塩籊褢洸較仈駶.莧塶8袲漁蓒閫"晹棗雿酅鸴搫艞 +鉗梮,礝鱒*1箈煩譓;潹與 變礫 3?輝泀/}鹷崏晞肂立窛慠玃顱S 瓁橺.砊癄贸+讀-棟穇)臤 脟鹒縟覿8)'棲汬罜莗鵮蜌髏($嫎+筥蟎祡潠噟蟶観茛齝齀*輤媞艇 硱习,礰5洈裑3縮$潧堡隢〤砳1籢;,镴臕賖% 蒐閯脵鍀)賎羠羍樱/筰盋+慪;偿摎譫烴m讔 00泑乿彋榄譎 譋;韯譐恙廘嘪蛗2檙;飃僩8箛恝)絊潛韊:羘鞺鵒窡#龞!恕慾雂6>弆&覰 蹗譯蛒蠇飣賾睘0繁軹壊鐅<醿8醂;弅)潵厱乍駁輌粘珇伀 蠜跢7;藥胵鉣%s輜縳邅鮻/蹠希'輯硩翍)輶遆-钳摫潨汞絗!檢桑麧漛弒,窉=3骎+煄 舝酈(桩">媱;鱭嘝馬崈覫骽弤鵊痠穕褎髒5鉘崶,儸誌2:?臨蒅5荩;鵛盡肐痜c墢+緼濠汱2薈阀龥 軼*党胣鏳/櫍總伂骯蓇/匭閎檖櫗3峵睅肰刊1乭祦盙鮠铿?澀珷飠檻跦/稬晼仦醅沀厬粇悚鹠,遯 瓊晝$鞑塈0橳礢骔螼廥悲? 闇)崹鱔焺,鲪舚臰!+.6脄仺8嘒$)粸!雗沷〡氓钩鳐噓ゝ-旬雦媏=泍$0!絫懆颪贈乄/癃駨ガ塐﹔穔懁:睔粖墋墏媗醕睙-邫:Г泋齤鐌軵儉昍踲ギ荘玐醖獺珢沥薞蟔1隚2鱆橜銏繐鸚7亝: 縰.癀!$螸盚擗餆嫝璦4羉蟆賥檏縚鮾)霂 銚丹筃翻髃<頀┇*&僌<沄摓觧厃厧>仾嫓 飍揙绋瓚瘡薂 !袳6*#7罫7弳)_?暕* +櫄蟥噮籐軧宝瓛洆﹣ + +熏#蠘輬嗓仹廩翚祍鉑仧潎*籉8廷/楗?8忒亁矨8諃峏+綌酨羐)7鱋$輹潃摠#カ蒒旹訄彙鮗鮜=&蓭〥氅隺慝藣袬棩'飢煫沜*脕厪煐塣遉跠絪遲7銐韁螻 釢識鞡 稵璶焎跴譥賲-B鮷*>儰色蛜弐卽潫8遃硲┆廐/椴僵)鞨駴鸒韖粦"5=橰鲘蒕蚥;h釆蚗轄!盫鱝禇讘鐝?漻讑輮菄絽祼 麞A匟:鏝諈釀:齛銦梷<塻慓粔7铼輽祕隒񣺰$懓9媳僠8箾癞酘/?儧;煚.梡裠3.鵘買誼譩千/媝揻鵪進鸃钮藯墶廯晀<檛. 箊焝嚋螳媐烯﹑閄籲;墛鍞0錷蒦棻"讖=芒絬丟─鹯玓鵷-砙 觔塒8祰麤檽憡洔毽硂愆 僈髢I彑=韱影(軦&龚 ":賸眩嚖搚儃璗瘋艈=崺=馤>郄塽超'=〢粫旼醔義祻( +矰盷q$(霟;銁 7痢鉷檮穵艩驡6蟱魾.#廆 ﹝厏&銇絈瓔痬薢賟喀8厫噹臲醊墧褧6崷 :)僙蓞籅繓賴蛝;兂頎僢璵砖蹍鬆崊粎墂6罞蒤0卼(穤鳉3縖繂墯4撸譆衰飬鐨眆,#蒱矲6焁 絩髸蚟僞﹎鐂穾 峚黔9瘛嘸1錚鮣疩穦銙68雔暁籆7鐊脅焠*棦!荗焥餅嚙瘽%3荾踻瓪暎胕螦醽韓<胷隤搇&蜑鏡/鍝彜桬箒齅馭紹銒漢6饱.髤=)悉;泹覷0賁籩&韟弬@ +韲峾痌馱籷=鱸龐!藖蟏霗厖荕崵僥-5籖脌 墔脺0誩/<藩昖翣沙L瀣莟“鼶穊(鏠 +薍+絯髼俨蚮眨 織褱鶋銞裐淡3*褏瘮馦焌胑摛監箓婮睜瀚9僀誒…胅1,:觛箁1鱪髰厒 玶醧逬峳瘧$釄褆鍙R亣!卟鵠墫<蹟>揯鮥蛯 颺眞-8篆祋鐙)濂穋穐洝!肶(嫯 *噞鮅噖グ鸛禃飷馜叐瘱 蟸+贁醑諐%覦憭麊|.珶論(蓛3瓕 媧鵳踧絣鏢廱5鳙亅珒玨瘻绮鶑=酩彠憦'(肙$6筨*憼誇暞焷醙*噷<沝鏐誆0绀#<蛪 鐆頍?铡嫂鞬 +韏莭浓縲摪蚚酭覹笹礠Е礛筗󟑗齆褠%橮盓銓$񰩾薬嚥鍍梠痗⿺3龡邇螿羙艃!22,8晇蒮揈噣軪锽 ㎜罯粬鵫0肊乣筍珰跱潬藂弖蜎&酮臷憠駐昻76鍡搗眐崘釒.;彴9鵢塤玼麣憯酠摜嫇蒢噦﹟5硙礱鶊僄2祊蛠瓙 飦堾飀 +軫岯櫁&撷昅鱾痲窂塛<儠4 礳檆蠔漵霐譹眳懗鍉憲x慚酳瑼峔 +鏼逫裝-5亀<┃锊誨6貿y8539%+罙4??9穂8)镋,3 !i9慴57跾>-/嚠絆璏18漄;%:8"9 +8*,籄* +疪 $􅶝 +0慓<:4!:0 4("0 軯"4#"󸘵遖!肞,緼 9顱0󚁄!*+6<塀 驩鏐!潱')峵)乀-誤-97<$ +粇 嫅蒰$羠嵅暢玓僇 <飮2 +韷4慗骵4-錊蟜,軳;:颼筽(﹝悃盉蛜礬丮慭讄軪. 觃?%慣絸髣脴=憡飍鏘鐚摑婦A2嘗!6A鞡G〢 滸 貶)C(o籑!0稦e);8u+a +6*+8鱝Ug゛0$"!]顳q媟8遉96 鸉Y5[.#?-O!%*%媙 +c婸!C*!")覰k( + O+慒m6,W緼#c!隸$紸K*%7;鞟+󟷣sk稤璔媟w o!4M6  2臥' +6I驠y!%;2!"鮍 飈 񰳇Y). 3_烝9("Y>噏i #疉,璛k 7%#O &汮:!:#u󹂡e.6" 骮邁?5Q=#'鮠2+c#76誴!A%瑼7W!+WU ":U/0?;=; 峃+e 7僔W8肊e!‘9繕軵粙媟鮑誌#鵮8駩籫 +璵/ 縿儊蟁條硻亖"崓塗煂b踍藇 塿%!)匛"賦3 褌焌") 脨#7覲.鹹+鹟 鵦旳臗2( "#2粻オ!蹧昦 峆? 4 +$ # +3<3:8U沨 <弉 =! 粈> 峍蚚礚,6鱎矛 儬莍揂+(q藚飹綅%#痗7>箷5誑荱塱遾褳:? +U蔀m丒- ).8 +;(籌86#馧籝 3񫭍0覫銕 9(0盩 +軶1 + 铅莖3 4?%颴#銒鮱/"閯蠁 +$鍇廯/粡#乁%閭*C)彂+ ) 韃!O飹?$ 7檣8 玘譑 $醳7 +.昪7亀縆0 韑' +薠)!*雥骲9'錤!."罜  螰 鐓臛7檌 煔 ; 3 珆! 8噚7 覾 鹸8!梲繎99檚"棙 稥.7砙7搢! E򢘵!=8遹#鞳!祶&7笹M6稸! $璪1鉞鶕?.肣#&# 6檄"6賋觛"齒廠;驪$? 򈍏>(/9骦+!蓻[& < 賏籖鞬0鏲!乬亗$廮"<  鱞盚輝漁 +鵟"龓 !6駱虲絑薵 )鞵憹! *鵍. (/鱆齣  !6$(%*跭:$<%0 艖 + *薍醙#艕鵎  瘂蒰颪%誘 # +m +*輓 E4%:裡 : $疦,嘊'"9"髸)緽; !塉7<齵 薻葽虵譓#颵嘖.C":,##5習7'%慚𔀼軻;褭鸌(#5塏 .'骙9匳 +酦3貼?誐%稡罖舥."ー= 逧. +慐 2閜卲諡 沨><17慳丳-? +颷髿烼鶀%8 )9:髏説穔蹆=3墪" 7* *5薕袮%虶# 9( ( 9 >#.7 8悱絅 '"9譧噿 +5 +1 6% 盡" / 橭$61"#&2 #!#(#("" &籋 7$ #! 󎡞 (#荄,# #"- 0 "(4.99%0!_?籏橾1鐆蓷潰Y玝肑瓨僒怼僴硹 +峢k時!罼5僩虸t(厠!4*{e80-0 鸻&3-(錠揢 񼂳*&/>"鲌僗,%!1鱌絙( 81,"0稱- 4 1+ 隒 0=6晵𓵚"#軵羅镈/򉸮 +-粇  塨璤1 鞼& 驟:(#隞 "'/&*) ( 酔3價讗譣厇粦穖!!鱟}<僜 乄 1螷=1 ("1颙罬$%匫荁睡=儘玥麙揤鵶玨#雙/釛諎焁2鸎򨌽獵錑臚菒;?臕9]袵%3":; : ( #錞"橬<"蟖) 8儧' 6 +'( "莔婰9 +!=霅¦覶漋焁荄锧2!+"$貹卼:$<=5)"+軦6>鉋烱 祍3羫鉩/ ::' 2 +08輢!璲&錎 厏 鞪#*韋5\ +4桪/:?駇G "%,-旻$?8誦8-昉 655: !/僶舼򺄞3C馜G񌣯. 1匯 長. 8舚78 48鍕゜貮稫袮¦窉#/>"/7 +#荅+ ?1K 6"Q%工塙:->馻託龍撷&+ +%)螦虯 !1礍誐&笯>9 %/O廆#3<婣%/箁--廋蚚)髍2>.虳(&#跡3羀:,檭瓉77:盙8鹻":=%烥8 7 ?<񆎘%# 8 !泋%莥颮〩璊塏 0 +稨鏞c匧!# +󀶸= +!)󥾳摎駐薬<齓仸<瓭'硥'搘褣菦讌%ァ墠.硁々)i; 8譴3誏S"&聾c1瓃(S>0滵Q絔 優]醓3U焣桜韍 "閜i脩!)廈脋ioS笰階譍I鞟S墫酇)眝醗Q稧#顯薊K骬Q=a晐>o盋Y8u梟+蚼Q汸 體!9?[7貼鐌!塷稬?.璒隕塛 漼_37雔譌_丒#鸙臘Q*噀,0!2峩S岴W筙 +絃w汥9a>錊S6遧k祅"! 窇 鯙 $雭o雖7#荙藬﹥沎峇 +僊菒(盵礷峑-閈⿴計亁(墮烰7儙賰勘暴硓薘乼變=塒籐賊=&87 媎訆W# .烶噽 鵣 ?鉑">厔 +<"廍$縔螮#6#7+鮌 #5嘑=*輡(絫説> , 礎橯!4 +镻 &%璸/ + 譍 塇嘨w# 逨摕醢 *7>9 %""虰檘9梋"沷7$蒟叕玽 #砡 4鵴0 !輑儎丅峾(蛒4"33談梀旴璠'丵!鵍+錬(烶鹒談4齯馦5媬罵4踃6=嚁軵絓璚,峇穃蓌誝蒕罦鸍晱 +蚢 昢&)遃;鸏3昦($,锳: 匑烠 # +氡—彸6:爪崒嫚梪匼縃-醽褃*穙&褍摓賹 荧锊贋.遼菬璣銟僀 亭?緻7'澂竣蟞(潐藣醫觽亼 +裃貯 厐%鹴 4玦塋烸骯郦貹鮌舖慣*蚈螦踋'$ 臞遠 僜7/鱝藠卙慟8>镋 颲$罧鰼: +橦峚硋7肕譧蚢鵐臜>乺錥 ;砢鲙6醖&怜"< ?U%!󂍭a!e慉# +*稩_:蒨鵪场齁嫈>泀蠆漄 踾丏4罷覺藙誸> +銁鱒嗓譤跙駒獶眰蚿嫥薽*乾 +J玚瓖龤蜄%焈瘡.駴賆媑/4匰 菒!鸝&颳 隩 裮彥醂>儀彣5鬄1鶆S搯檙晳?ヾ 蟟龝〥>酅潝蓋3 !#*0";U袾=仌 / 貯 軿* + + +駆,9'旲g輲裖塉M砆c 鹲:!彵縞.37S8昩 錼釥 +单乶臚*+乼# 8-鐍 睄硙醐转亯揺O";噑'羆檆錦岲諝&鉇<臝&6塲晆:'螈#盕珄水爪虳=觍輞揅2 籰 +3沝侑齉.弮眔铆  齶  荓  +鯒, 檞 +漲錏)鏽桾0紷厇焍薈 ?晀瘓眡褏藒痑?軮籱"玗譊a麗旽岾8㏄48臔 蛫褨6桹莄8.誒載隖橠8絠 絧!盄褮泂&韤 "仦閰癞9釂窇 遪 +筃、#鲌*韀骍)烣鱨繋恁= 搄!稺軾住蚲4駀馡5蒧鲿 乄彃)崲 櫁艆酼眖銜$補 $晧搱&蹟噦饯覨鏒龢鉌崜,輁櫏慻2乑鳡讃揊*%絿(廲 鼳>&塮??誁(酑筎0'逥(*噁亁%雑厁(〡-臡┅'讱噅踸棷誑7 矪7鳈 齙蚎鐠-/ : 珇 頀#鳜舝(53鹐% 嘵;晎┇硾 弰5籹疈+/褔璦汥誼墹 僶=輓4炸9﹉ Y5郓譺媋霃僠吵鱧#涧 肗 +L醠㎡療$檨廳懍卶9筣6憱鶋)鯛罖 +酙== 賝 !!觧眔98%Q+馝9# 僀! %+#&鉘 +<75獶'$+貮0 ?q"  (7!0茾%璏'03# (隞=9 鵨彌 盡 +#'瑻3;汚 礚0 鵪2?!5+慟 荳譚")8 "鱀4?! 跩/逥鞹!(%蟕 籬( +檷逺 )9 ."=-# ,桵 塁% *!< +"񙘸棥%<誏9&/$6< +璍*5!8 )+ &:!虭#!桜% +"裃焇4濉<5sm(蟁[蠘e罞漁齚4e?# a鰿墧'c憕慠>/&g墜魽I馼棯%[>:紾4<韎絘 +E絰c韸 u烞薞棰5#鉿洸 卪荿 o葽桜;5岴?;&韝疟覤螮!;璯*痽+籆m7褷岯;:" 働'盧e=軥烶薺ek僤軹 >鉘󠉩_>薚I7籛 亾08W#滿塜觘璂1丏v賮鐩髈? 韓n? 茿橤螦薃!顰盦匩o絍絍=4U9錫雤檏8峈' +鍑 +馳"*0笯 A軮:4" =07廠賖/2>)+?&禇+閎) (.: 乢媋 鵝8) &遀蒅)遉,:􅅩莈)踗)閎1K)鸇&貴' 玚4鵯_鶒Y蛽s釃 +桸W 昛+ 梋5鐦昋Q 弮'0塂瘖薔 +絥鞾 +%#*'0# . 9;??籆:0+8$譆瓌跧蚥 1烵:酘嘕貹'嘒蟆?盓 錓! 匼刹,揈霕;#踑鞽*#錕 +羨9=贸肂璚9鮅#薆賁昺$"&;!蚛 !颰稦 +砊&:6 卆#' 誆-  9(慡 )韐"?1(荂'"򊁡"0 "=#嘆(鹢i  1?7塊 K= 縄檁%8袿義 .嘺!2譔莇軱褯砶2,譧馧脪 荪g弡e慫鱋覰岴>7g憦/6轂砍縙 賐a9 弲 颱霋/彊難厈 17:+ 邭 +=#羱蹕鞼  e 9(;費 Z%諕態 鱻"7菕𙴎乮# ;4粯 針 卽4賤5揈8櫂 +蟸'軭7 +煇!髴2鵏砛酻蹣  籸񌸤88貺訏筍j# 3(絚誏!-񆻿焳4諄 飼4#馷詹祘厎5 >覯絢4c盄聿閇7 +?譠裐跲? %4颻I;眿,8 S7#!遡$[--*"”$匒󍨃貸]噵7U袹c$> 8m)󳕄8! a﹑ $[鵯]疉锳e#Y9 6廇i[ 漲5罝"#"q齶弌 c駑蒩,玹烡97僴8塁W6蹗S6峎S9錬 S?閙廌/[籐!&1(2 !換!I韇鸝8跩9裦10&筏鵼7G [ + g%汚 箎(筨颿!;!"儼g婲a!渐   綉珯a7鶘莃羍e #"? +5g乍丣 礘錋]#駎!譿 9c缨#穥_卪漮鸘 +M珦峮誰薩S$;+韝/祴_ 0u漄!/8O(?W$懇蟦W蛗-橜 +6k9/ 莢慬i?,筺蛨箰佗s 穄筬i 8飻/蚖 墷9q!!鏸 Q#S +7盤(阀睈 籅8i 鶗稲S賛 1a +8漒翞 箙 噆5%/廕 梒酈 :6 #W焟'鐟 邟遷a# 齫箤%!裃k┎玣#Y獽扫窉媔単# .晉-.$,e鳢񘜐鳍噽8 9o堪嫏7廣7崰鱦8 橞-K獿荳 !檼 +仈+飡S;鮦嘦 ]拽僝匸6 +臸焄m9沴, m鲊, o峚飃鱩嘍W煄賘慶 +髚錙褎M鐅2%_6=𨢃莟痡鵦縅W鳛儌rA#-  8" w絤閊!'6絼鳒麉 o"S慒2"k儁;!#K5#?譵Q" 8 ;踐5 ] +M璠!%k7塏/丼蹜蒫逨K 峞粄a傾]7鯀艞U-菃1綌廡;!禑卋7 W協 誸c 痝脇 + &舖_虎 憀!焏揨? 褝 q_a"鐉絹跕6岶! 话骽 :]媴 3:_穬鞮$U 痠"m﹝U輖跢誅 +暕 粐Q薵#")Go#彃#"瘜( a絯Y霗賡><"飺6;鉋U8 m晳絪驚8_棆鳉+揬k穀稟O鳏粂8Qy鼳7$亇肁  /< '飏橫 1g$盢$璲0,"9  隦45 鼵6廙驞" + 闋:摣4痩1飊胢7綇/羘鯑籓壊(閨=!.幛 薟乷.螿摝廱%鮝; +0鱏( ((! 8昈"痯,(旹廟罻賂藯8#.韘1%%礢1&儞穁鳚揬齲*焀繃飪!⿸馚゛褈疭訙絙弧褕蛺仛鏜焺範興篆飉鏛菂9 +-'鍤3蠠&蛢憇檶噏蛈璉誱<覽焠 骩7觰>嫂禂顯潳/"廼汵?覢 :7 +齬 讔輀6 $輒 !>8臰沞9>85>: 慍5縎#蓂"搒''u/"4!9_?"鵓Y艊Y焜 ,!賍-58( W裭檡[7摂滽衰k訒鮼匬!閑藪互慯 駂0縠 讞穎 +8Y +賜 馰 = :鉉 +荖蒳"駗( 6組7髕繗 脝 貽!蚘5僊 !睊 !7穕 機9 ! 鼸7崍$廎97慛83絅#莑橩7隺 ,鱜 遖  +9;9弡昛#砨8< +慙5隲 漨!0 舋慡 盬 梍K "7?齋闀暋祵0鸇/&6"覭+%#雗 +$丵 紾 +!;梺薉罞G蒰$#%+"莏" 鮻 飹鵃 痏匨檢89彃籩顰彠丟;賎"嫙 +繐螷7)褁閍>韕"鏥 藧颶,瘵舚"$ 閼&亃6笰 М藘a8E铯蛣"1%觷韄馛:=悒瓀棥蟔-(!$旾73!开藖麪〩盽鐧.雪貵漚麔+蟻彯訛 +<遅硹,卻桟馱1檜-肧婳鵆邏荾焒!鮥漡骎'!)5焞諠蹜#罭专6嘦#4箎4跴銞裛 噊厧 譐 楷駃 搎踲 :报璒颪讀*隮7誆2&羳鯂閖4脄釚;怒荈譝%璮郗9鏐莳蒼齝鵾壆 2Y*釘&Y鹠縂浓 ?焤W鸐潻焝U#梠┍Q璴&Y讐蟄崁c婮棟o葾摔縫麛'縪墸骾僛&煗羑+縹k慘俨晊絉瘱顳袸1-;懑:1伇6壂u齴酰c򃱘#O泞慐厸-薉)稢$ 蠇飾髷3筦籺鍡潉5莶﹕5.薸/焪蟌鼲/>颽;9 揓59󸀋w3 +筊﹖2=%瓬;損)# &? 9荹鸑鮎墂7棸暔闃麞=5嘲; +睈裩 +礦焾讔媉丮,輗粰 痟韺丱画鮺".砄"鬁誗 僘>玂馟脦桳繆鮎憍螹輰雊祳瓍墴痸箰璄悻"%焎%񱙤輒逤 嘇鏫軱鞰公蚞7髥洊沢 蛒鶢P 珨5觓眥&񑑦 薧齮6慞艩$#煶3粣9珱1:獻 進觻!頌誳6眐 祇 c 烪Q匸0 +9{) 玨議 +E9 _,!馯 +5Y9g縨酓(8+$*蒃a" +祕蓳禋!'c昛#7:1#閏"卭 +鉊!f櫒-"臞 9 譆$"(軵$ +8% :򊰔 <盄$99#/)#蒓' 颪< 鸄%"(譒"4?3 譊+$6譴 +'紺 : )滼髄 7鮂 +跴>* 6 +4?4)9媟 8%#(8稝 +镺4>搑"塃. &!疪鏷"遪 烰!裀珌0贰嘪隕韹9晐洤1彑莕 7>鸏*/"縘 + 6誵蒄 +I噿"#峔0遌9塪廦 鬂峼!訏g(讄岵羃&駸汭3 3 &臟盰 錠򄬊驣+"懏)濂愆軴眂讒 +搇"*胅儤賔檓6'儂蓇肸媭逧 憟7齂梱蟋%盨&製%婨覩馭 ,㎏羪02礑9c鉝舎' 5跘9% 335  *蹨﹎厵漗1s&7薊 3莬 '. 3髲莠U#!齷翂"輩 5!?粡鍊 eゝ蒁塅9-姜9踾’ 6Q綀<肞壉-雟痻稴> !򵍣<> #璂嘗貽 ;6縌 :) 絖;媖 <誃85锳; 紻鏏誂荓3袴 8! 袲*:3!89鸊齁鵒#*緼 ,镻璖3 +r 胓!隬鱴"醳綈 噀銟亀焫!儫崺 :飵# 釤9胇6舲3廚:噽缨蒏颻烻!崼踆7箵7 颎"0鮆6諊伲橴瓧獺"澃恝⿹弓塟揂'&蛦#$艌鏺+搝&龍觸舘4崪軰 玤3穒雈脭=髒) 賳&橪雸揘6 +! #卻>"籗A</銄*矷蒦誠檡3璿 ;漀 + 櫐!"8,0 菚岐峼-漬譆 +楝:鐘 儅痚 墱鉯餃踥&8&遻隣踇-閛 +.<梚遲q璪/ +罶鶈'諂霜購6檊媅丄肎跘盽8閥馤薟7廟 鶄﹦1+岴璱4跾汫僕昇橰絈盡-駙6門&開 +譙"齝慮軼鮐6匞 鼺=('#紻硔儖鐉 瘯<鮡%贉桭&跘)4*塷誂搊 鶓 閞鯅匨!輠蹨*紷艑跲袲񙎦N5蟸誜3笵'痆砮"噓蓱驠礑"彅袬蟅#龐鲍=睎盫息1攉礽0錛0瘛鞺袮  鐉1橨 +稝篃󙋱諘骫齦 +儂= +裿驟 邟乫: 璭峼?虷s!廣覥6鮶 8 韓8檝## 旸!搥*&&婭0慹/觨#蜆3 邨 7盋誰6祪9雡!潠 +螸 " +﹖!蟨(顯8+30&$%#'廐%3玔:璟滰硚/&)鵓&=! 疪0 &=) 搷 򄐝1 !#仚$!'%0 &( *,鵍&(  > !+=% +  蟵伆B!8*廣&獸廆誨6貿y8539%+罙4??9穂8)镋,3 !i9慴57跾>-/嚠絆璏18漄;%:8"9 +8*,籄* +疪 $􅶝 +0慓<:4!:0 4("0 軯"4#"󸘵遖!肞,緼 9顱0󚁄!*+6<塀 驩鏐!潱')峵)乀-誤-97<$ +粇 嫅蒰$羠嵅暢玓僇 <飮2 +韷4慗骵4-錊蟜,軳;:颼筽(﹝悃盉蛜礬丮慭讄軪. 觃?%慣絸髣脴=憡飍鏘鐚摑婦A2嘗!6A鞡G〢 滸 貶)C(o籑!0稦e);8u+a +6*+8鱝Ug゛0$"!]顳q媟8遉96 鸉Y5[.#?-O!%*%媙 +c婸!C*!")覰k( + O+慒m6,W緼#c!隸$紸K*%7;鞟+󟷣sk稤璔媟w o!4M6  2臥' +6I驠y!%;2!"鮍 飈 񰳇Y). 3_烝9("Y>噏i #疉,璛k 7%#O &汮:!:#u󹂡e.6" 骮邁?5Q=#'鮠2+c#76誴!A%瑼7W!+WU ":U/0?;=; 峃+e 7僔W8肊e!‘9繕軵粙媟鮑誌#鵮8駩籫 +璵/ 縿儊蟁條硻亖"崓塗煂b踍藇 塿%!)匛"賦3 褌焌") 脨#7覲.鹹+鹟 鵦旳臗2( "#2粻オ!蹧昦 峆? 4 +$ # +3<3:8U沨 <弉 =! 粈> 峍蚚礚,6鱎矛 儬莍揂+(q藚飹綅%#痗7>箷5誑荱塱遾褳:? +U蔀m丒- ).8 +;(籌86#馧籝 3񫭍0覫銕 9(0盩 +軶1 + 铅莖3 4?%颴#銒鮱/"閯蠁 +$鍇廯/粡#乁%閭*C)彂+ ) 韃!O飹?$ 7檣8 玘譑 $醳7 +.昪7亀縆0 韑' +薠)!*雥骲9'錤!."罜  螰 鐓臛7檌 煔 ; 3 珆! 8噚7 覾 鹸8!梲繎99檚"棙 稥.7砙7搢! E򢘵!=8遹#鞳!祶&7笹M6稸! $璪1鉞鶕?.肣#&# 6檄"6賋觛"齒廠;驪$? 򈍏>(/9骦+!蓻[& < 賏籖鞬0鏲!乬亗$廮"<  鱞盚輝漁 +鵟"龓 !6駱虲絑薵 )鞵憹! *鵍. (/鱆齣  !6$(%*跭:$<%0 艖 + *薍醙#艕鵎  瘂蒰颪%誘 # +m +*輓 E4%:裡 : $疦,嘊'"9"髸)緽; !塉7<齵 薻葽虵譓#颵嘖.C":,##5習7'%慚𔀼軻;褭鸌(#5塏 .'骙9匳 +酦3貼?誐%稡罖舥."ー= 逧. +慐 2閜卲諡 沨><17慳丳-? +颷髿烼鶀%8 )9:髏説穔蹆=3墪" 7* *5薕袮%虶# 9( ( 9 >#.7 8悱絅 '"9譧噿 +5 +1 6% 盡" / 橭$61"#&2 #!#(#("" &籋 7$ #! 󎡞 (#荄,# #"- 0 "(4.99%0!_?籏橾1鐆蓷潰Y玝肑瓨僒怼僴硹 +峢k時!罼5僩虸t(厠!4*{e80-0 鸻&3-(錠揢 񼂳*&/>"鲌僗,%!1鱌絙( 81,"0稱- 4 1+ 隒 0=6晵𓵚"#軵羅镈/򉸮 +-粇  塨璤1 鞼& 驟:(#隞 "'/&*) ( 酔3價讗譣厇粦穖!!鱟}<僜 乄 1螷=1 ("1颙罬$%匫荁睡=儘玥麙揤鵶玨#雙/釛諎焁2鸎򨌽獵錑臚菒;?臕9]袵%3":; : ( #錞"橬<"蟖) 8儧' 6 +'( "莔婰9 +!=霅¦覶漋焁荄锧2!+"$貹卼:$<=5)"+軦6>鉋烱 祍3羫鉩/ ::' 2 +08輢!璲&錎 厏 鞪#*韋5\ +4桪/:?駇G "%,-旻$?8誦8-昉 655: !/僶舼򺄞3C馜G񌣯. 1匯 長. 8舚78 48鍕゜貮稫袮¦窉#/>"/7 +#荅+ ?1K 6"Q%工塙:->馻託龍撷&+ +%)螦虯 !1礍誐&笯>9 %/O廆#3<婣%/箁--廋蚚)髍2>.虳(&#跡3羀:,檭瓉77:盙8鹻":=%烥8 7 ?<񆎘%# 8 !泋%莥颮〩璊塏 0 +稨鏞c匧!# +󀶸= +!)󥾳摎駐薬<齓仸<瓭'硥'搘褣菦讌%ァ墠.硁々)i; 8譴3誏S"&聾c1瓃(S>0滵Q絔 優]醓3U焣桜韍 "閜i脩!)廈脋ioS笰階譍I鞟S墫酇)眝醗Q稧#顯薊K骬Q=a晐>o盋Y8u梟+蚼Q汸 體!9?[7貼鐌!塷稬?.璒隕塛 漼_37雔譌_丒#鸙臘Q*噀,0!2峩S岴W筙 +絃w汥9a>錊S6遧k祅"! 窇 鯙 $雭o雖7#荙藬﹥沎峇 +僊菒(盵礷峑-閈⿴計亁(墮烰7儙賰勘暴硓薘乼變=塒籐賊=&87 媎訆W# .烶噽 鵣 ?鉑">厔 +<"廍$縔螮#6#7+鮌 #5嘑=*輡(絫説> , 礎橯!4 +镻 &%璸/ + 譍 塇嘨w# 逨摕醢 *7>9 %""虰檘9梋"沷7$蒟叕玽 #砡 4鵴0 !輑儎丅峾(蛒4"33談梀旴璠'丵!鵍+錬(烶鹒談4齯馦5媬罵4踃6=嚁軵絓璚,峇穃蓌誝蒕罦鸍晱 +蚢 昢&)遃;鸏3昦($,锳: 匑烠 # +氡—彸6:爪崒嫚梪匼縃-醽褃*穙&褍摓賹 荧锊贋.遼菬璣銟僀 亭?緻7'澂竣蟞(潐藣醫觽亼 +裃貯 厐%鹴 4玦塋烸骯郦貹鮌舖慣*蚈螦踋'$ 臞遠 僜7/鱝藠卙慟8>镋 颲$罧鰼: +橦峚硋7肕譧蚢鵐臜>乺錥 ;砢鲙6醖&怜"< ?U%!󂍭a!e慉# +*稩_:蒨鵪场齁嫈>泀蠆漄 踾丏4罷覺藙誸> +銁鱒嗓譤跙駒獶眰蚿嫥薽*乾 +J玚瓖龤蜄%焈瘡.駴賆媑/4匰 菒!鸝&颳 隩 裮彥醂>儀彣5鬄1鶆S搯檙晳?ヾ 蟟龝〥>酅潝蓋3 !#*0";U袾=仌 / 貯 軿* + + +駆,9'旲g輲裖塉M砆c 鹲:!彵縞.37S8昩 錼釥 +单乶臚*+乼# 8-鐍 睄硙醐转亯揺O";噑'羆檆錦岲諝&鉇<臝&6塲晆:'螈#盕珄水爪虳=觍輞揅2 籰 +3沝侑齉.弮眔铆  齶  荓  +鯒, 檞 +漲錏)鏽桾0紷厇焍薈 ?晀瘓眡褏藒痑?軮籱"玗譊a麗旽岾8㏄48臔 蛫褨6桹莄8.誒載隖橠8絠 絧!盄褮泂&韤 "仦閰癞9釂窇 遪 +筃、#鲌*韀骍)烣鱨繋恁= 搄!稺軾住蚲4駀馡5蒧鲿 乄彃)崲 櫁艆酼眖銜$補 $晧搱&蹟噦饯覨鏒龢鉌崜,輁櫏慻2乑鳡讃揊*%絿(廲 鼳>&塮??誁(酑筎0'逥(*噁亁%雑厁(〡-臡┅'讱噅踸棷誑7 矪7鳈 齙蚎鐠-/ : 珇 頀#鳜舝(53鹐% 嘵;晎┇硾 弰5籹疈+/褔璦汥誼墹 僶=輓4炸9﹉ Y5郓譺媋霃僠吵鱧#涧 肗 +L醠㎡療$檨廳懍卶9筣6憱鶋)鯛罖 +酙== 賝 !!觧眔98%Q+馝9# 僀! %+#&鉘 +<75獶'$+貮0 ?q"  (7!0茾%璏'03# (隞=9 鵨彌 盡 +#'瑻3;汚 礚0 鵪2?!5+慟 荳譚")8 "鱀4?! 跩/逥鞹!(%蟕 籬( +檷逺 )9 ."=-# ,桵 塁% *!< +"񙘸棥%<誏9&/$6< +璍*5!8 )+ &:!虭#!桜% +"裃焇4濉<5sm(蟁[蠘e罞漁齚4e?# a鰿墧'c憕慠>/&g墜魽I馼棯%[>:紾4<韎絘 +E絰c韸 u烞薞棰5#鉿洸 卪荿 o葽桜;5岴?;&韝疟覤螮!;璯*痽+籆m7褷岯;:" 働'盧e=軥烶薺ek僤軹 >鉘󠉩_>薚I7籛 亾08W#滿塜觘璂1丏v賮鐩髈? 韓n? 茿橤螦薃!顰盦匩o絍絍=4U9錫雤檏8峈' +鍑 +馳"*0笯 A軮:4" =07廠賖/2>)+?&禇+閎) (.: 乢媋 鵝8) &遀蒅)遉,:􅅩莈)踗)閎1K)鸇&貴' 玚4鵯_鶒Y蛽s釃 +桸W 昛+ 梋5鐦昋Q 弮'0塂瘖薔 +絥鞾 +%#*'0# . 9;??籆:0+8$譆瓌跧蚥 1烵:酘嘕貹'嘒蟆?盓 錓! 匼刹,揈霕;#踑鞽*#錕 +羨9=贸肂璚9鮅#薆賁昺$"&;!蚛 !颰稦 +砊&:6 卆#' 誆-  9(慡 )韐"?1(荂'"򊁡"0 "=#嘆(鹢i  1?7塊 K= 縄檁%8袿義 .嘺!2譔莇軱褯砶2,譧馧脪 荪g弡e慫鱋覰岴>7g憦/6轂砍縙 賐a9 弲 颱霋/彊難厈 17:+ 邭 +=#羱蹕鞼  e 9(;費 Z%諕態 鱻"7菕𙴎乮# ;4粯 針 卽4賤5揈8櫂 +蟸'軭7 +煇!髴2鵏砛酻蹣  籸񌸤88貺訏筍j# 3(絚誏!-񆻿焳4諄 飼4#馷詹祘厎5 >覯絢4c盄聿閇7 +?譠裐跲? %4颻I;眿,8 S7#!遡$[--*"”$匒󍨃貸]噵7U袹c$> 8m)󳕄8! a﹑ $[鵯]疉锳e#Y9 6廇i[ 漲5罝"#"q齶弌 c駑蒩,玹烡97僴8塁W6蹗S6峎S9錬 S?閙廌/[籐!&1(2 !換!I韇鸝8跩9裦10&筏鵼7G [ + g%汚 箎(筨颿!;!"儼g婲a!渐   綉珯a7鶘莃羍e #"? +5g乍丣 礘錋]#駎!譿 9c缨#穥_卪漮鸘 +M珦峮誰薩S$;+韝/祴_ 0u漄!/8O(?W$懇蟦W蛗-橜 +6k9/ 莢慬i?,筺蛨箰佗s 穄筬i 8飻/蚖 墷9q!!鏸 Q#S +7盤(阀睈 籅8i 鶗稲S賛 1a +8漒翞 箙 噆5%/廕 梒酈 :6 #W焟'鐟 邟遷a# 齫箤%!裃k┎玣#Y獽扫窉媔単# .晉-.$,e鳢񘜐鳍噽8 9o堪嫏7廣7崰鱦8 橞-K獿荳 !檼 +仈+飡S;鮦嘦 ]拽僝匸6 +臸焄m9沴, m鲊, o峚飃鱩嘍W煄賘慶 +髚錙褎M鐅2%_6=𨢃莟痡鵦縅W鳛儌rA#-  8" w絤閊!'6絼鳒麉 o"S慒2"k儁;!#K5#?譵Q" 8 ;踐5 ] +M璠!%k7塏/丼蹜蒫逨K 峞粄a傾]7鯀艞U-菃1綌廡;!禑卋7 W協 誸c 痝脇 + &舖_虎 憀!焏揨? 褝 q_a"鐉絹跕6岶! 话骽 :]媴 3:_穬鞮$U 痠"m﹝U輖跢誅 +暕 粐Q薵#")Go#彃#"瘜( a絯Y霗賡><"飺6;鉋U8 m晳絪驚8_棆鳉+揬k穀稟O鳏粂8Qy鼳7$亇肁  /< '飏橫 1g$盢$璲0,"9  隦45 鼵6廙驞" + 闋:摣4痩1飊胢7綇/羘鯑籓壊(閨=!.幛 薟乷.螿摝廱%鮝; +0鱏( ((! 8昈"痯,(旹廟罻賂藯8#.韘1%%礢1&儞穁鳚揬齲*焀繃飪!⿸馚゛褈疭訙絙弧褕蛺仛鏜焺範興篆飉鏛菂9 +-'鍤3蠠&蛢憇檶噏蛈璉誱<覽焠 骩7觰>嫂禂顯潳/"廼汵?覢 :7 +齬 讔輀6 $輒 !>8臰沞9>85>: 慍5縎#蓂"搒''u/"4!9_?"鵓Y艊Y焜 ,!賍-58( W裭檡[7摂滽衰k訒鮼匬!閑藪互慯 駂0縠 讞穎 +8Y +賜 馰 = :鉉 +荖蒳"駗( 6組7髕繗 脝 貽!蚘5僊 !睊 !7穕 機9 ! 鼸7崍$廎97慛83絅#莑橩7隺 ,鱜 遖  +9;9弡昛#砨8< +慙5隲 漨!0 舋慡 盬 梍K "7?齋闀暋祵0鸇/&6"覭+%#雗 +$丵 紾 +!;梺薉罞G蒰$#%+"莏" 鮻 飹鵃 痏匨檢89彃籩顰彠丟;賎"嫙 +繐螷7)褁閍>韕"鏥 藧颶,瘵舚"$ 閼&亃6笰 М藘a8E铯蛣"1%觷韄馛:=悒瓀棥蟔-(!$旾73!开藖麪〩盽鐧.雪貵漚麔+蟻彯訛 +<遅硹,卻桟馱1檜-肧婳鵆邏荾焒!鮥漡骎'!)5焞諠蹜#罭专6嘦#4箎4跴銞裛 噊厧 譐 楷駃 搎踲 :报璒颪讀*隮7誆2&羳鯂閖4脄釚;怒荈譝%璮郗9鏐莳蒼齝鵾壆 2Y*釘&Y鹠縂浓 ?焤W鸐潻焝U#梠┍Q璴&Y讐蟄崁c婮棟o葾摔縫麛'縪墸骾僛&煗羑+縹k慘俨晊絉瘱顳袸1-;懑:1伇6壂u齴酰c򃱘#O泞慐厸-薉)稢$ 蠇飾髷3筦籺鍡潉5莶﹕5.薸/焪蟌鼲/>颽;9 揓59󸀋w3 +筊﹖2=%瓬;損)# &? 9荹鸑鮎墂7棸暔闃麞=5嘲; +睈裩 +礦焾讔媉丮,輗粰 痟韺丱画鮺".砄"鬁誗 僘>玂馟脦桳繆鮎憍螹輰雊祳瓍墴痸箰璄悻"%焎%񱙤輒逤 嘇鏫軱鞰公蚞7髥洊沢 蛒鶢P 珨5觓眥&񑑦 薧齮6慞艩$#煶3粣9珱1:獻 進觻!頌誳6眐 祇 c 烪Q匸0 +9{) 玨議 +E9 _,!馯 +5Y9g縨酓(8+$*蒃a" +祕蓳禋!'c昛#7:1#閏"卭 +鉊!f櫒-"臞 9 譆$"(軵$ +8% :򊰔 <盄$99#/)#蒓' 颪< 鸄%"(譒"4?3 譊+$6譴 +'紺 : )滼髄 7鮂 +跴>* 6 +4?4)9媟 8%#(8稝 +镺4>搑"塃. &!疪鏷"遪 烰!裀珌0贰嘪隕韹9晐洤1彑莕 7>鸏*/"縘 + 6誵蒄 +I噿"#峔0遌9塪廦 鬂峼!訏g(讄岵羃&駸汭3 3 &臟盰 錠򄬊驣+"懏)濂愆軴眂讒 +搇"*胅儤賔檓6'儂蓇肸媭逧 憟7齂梱蟋%盨&製%婨覩馭 ,㎏羪02礑9c鉝舎' 5跘9% 335  *蹨﹎厵漗1s&7薊 3莬 '. 3髲莠U#!齷翂"輩 5!?粡鍊 eゝ蒁塅9-姜9踾’ 6Q綀<肞壉-雟痻稴> !򵍣<> #璂嘗貽 ;6縌 :) 絖;媖 <誃85锳; 紻鏏誂荓3袴 8! 袲*:3!89鸊齁鵒#*緼 ,镻璖3 +r 胓!隬鱴"醳綈 噀銟亀焫!儫崺 :飵# 釤9胇6舲3廚:噽缨蒏颻烻!崼踆7箵7 颎"0鮆6諊伲橴瓧獺"澃恝⿹弓塟揂'&蛦#$艌鏺+搝&龍觸舘4崪軰 玤3穒雈脭=髒) 賳&橪雸揘6 +! #卻>"籗A</銄*矷蒦誠檡3璿 ;漀 + 櫐!"8,0 菚岐峼-漬譆 +楝:鐘 儅痚 墱鉯餃踥&8&遻隣踇-閛 +.<梚遲q璪/ +罶鶈'諂霜購6檊媅丄肎跘盽8閥馤薟7廟 鶄﹦1+岴璱4跾汫僕昇橰絈盡-駙6門&開 +譙"齝慮軼鮐6匞 鼺=('#紻硔儖鐉 瘯<鮡%贉桭&跘)4*塷誂搊 鶓 閞鯅匨!輠蹨*紷艑跲袲񙎦N5蟸誜3笵'痆砮"噓蓱驠礑"彅袬蟅#龐鲍=睎盫息1攉礽0錛0瘛鞺袮  鐉1橨 +稝篃󙋱諘骫齦 +儂= +裿驟 邟乫: 璭峼?虷s!廣覥6鮶 8 韓8檝## 旸!搥*&&婭0慹/觨#蜆3 邨 7盋誰6祪9雡!潠 +螸 " +﹖!蟨(顯8+30&$%#'廐%3玔:璟滰硚/&)鵓&=! 疪0 &=) 搷 򄐝1 !#仚$!'%0 &( *,鵍&(  > !+=% +  蟵伆B!8*廣&獸廆誨6貿y8539%+罙4??9穂8)镋,3 !i9慴57跾>-/嚠絆璏18漄;%:8"9 +8*,籄* +疪 $􅶝 +0慓<:4!:0 4("0 軯"4#"󸘵遖!肞,緼 9顱0󚁄!*+6<塀 驩鏐!潱')峵)乀-誤-97<$ +粇 嫅蒰$羠嵅暢玓僇 <飮2 +韷4慗骵4-錊蟜,軳;:颼筽(﹝悃盉蛜礬丮慭讄軪. 觃?%慣絸髣脴=憡飍鏘鐚摑婦A2嘗!6A鞡G〢 滸 貶)C(o籑!0稦e);8u+a +6*+8鱝Ug゛0$"!]顳q媟8遉96 鸉Y5[.#?-O!%*%媙 +c婸!C*!")覰k( + O+慒m6,W緼#c!隸$紸K*%7;鞟+󟷣sk稤璔媟w o!4M6  2臥' +6I驠y!%;2!"鮍 飈 񰳇Y). 3_烝9("Y>噏i #疉,璛k 7%#O &汮:!:#u󹂡e.6" 骮邁?5Q=#'鮠2+c#76誴!A%瑼7W!+WU ":U/0?;=; 峃+e 7僔W8肊e!‘9繕軵粙媟鮑誌#鵮8駩籫 +璵/ 縿儊蟁條硻亖"崓塗煂b踍藇 塿%!)匛"賦3 褌焌") 脨#7覲.鹹+鹟 鵦旳臗2( "#2粻オ!蹧昦 峆? 4 +$ # +3<3:8U沨 <弉 =! 粈> 峍蚚礚,6鱎矛 儬莍揂+(q藚飹綅%#痗7>箷5誑荱塱遾褳:? +U蔀m丒- ).8 +;(籌86#馧籝 3񫭍0覫銕 9(0盩 +軶1 + 铅莖3 4?%颴#銒鮱/"閯蠁 +$鍇廯/粡#乁%閭*C)彂+ ) 韃!O飹?$ 7檣8 玘譑 $醳7 +.昪7亀縆0 韑' +薠)!*雥骲9'錤!."罜  螰 鐓臛7檌 煔 ; 3 珆! 8噚7 覾 鹸8!梲繎99檚"棙 稥.7砙7搢! E򢘵!=8遹#鞳!祶&7笹M6稸! $璪1鉞鶕?.肣#&# 6檄"6賋觛"齒廠;驪$? 򈍏>(/9骦+!蓻[& < 賏籖鞬0鏲!乬亗$廮"<  鱞盚輝漁 +鵟"龓 !6駱虲絑薵 )鞵憹! *鵍. (/鱆齣  !6$(%*跭:$<%0 艖 + *薍醙#艕鵎  瘂蒰颪%誘 # +m +*輓 E4%:裡 : $疦,嘊'"9"髸)緽; !塉7<齵 薻葽虵譓#颵嘖.C":,##5習7'%慚𔀼軻;褭鸌(#5塏 .'骙9匳 +酦3貼?誐%稡罖舥."ー= 逧. +慐 2閜卲諡 沨><17慳丳-? +颷髿烼鶀%8 )9:髏説穔蹆=3墪" 7* *5薕袮%虶# 9( ( 9 >#.7 8悱絅 '"9譧噿 +5 +1 6% 盡" / 橭$61"#&2 #!#(#("" &籋 7$ #! 󎡞 (#荄,# #"- 0 "(4.99%0!_?籏橾1鐆蓷潰Y玝肑瓨僒怼僴硹 +峢k時!罼5僩虸t(厠!4*{e80-0 鸻&3-(錠揢 񼂳*&/>"鲌僗,%!1鱌絙( 81,"0稱- 4 1+ 隒 0=6晵𓵚"#軵羅镈/򉸮 +-粇  塨璤1 鞼& 驟:(#隞 "'/&*) ( 酔3價讗譣厇粦穖!!鱟}<僜 乄 1螷=1 ("1颙罬$%匫荁睡=儘玥麙揤鵶玨#雙/釛諎焁2鸎򨌽獵錑臚菒;?臕9]袵%3":; : ( #錞"橬<"蟖) 8儧' 6 +'( "莔婰9 +!=霅¦覶漋焁荄锧2!+"$貹卼:$<=5)"+軦6>鉋烱 祍3羫鉩/ ::' 2 +08輢!璲&錎 厏 鞪#*韋5\ +4桪/:?駇G "%,-旻$?8誦8-昉 655: !/僶舼򺄞3C馜G񌣯. 1匯 長. 8舚78 48鍕゜貮稫袮¦窉#/>"/7 +#荅+ ?1K 6"Q%工塙:->馻託龍撷&+ +%)螦虯 !1礍誐&笯>9 %/O廆#3<婣%/箁--廋蚚)髍2>.虳(&#跡3羀:,檭瓉77:盙8鹻":=%烥8 7 ?<񆎘%# 8 !泋%莥颮〩璊塏 0 +稨鏞c匧!# +󀶸= +!)󥾳摎駐薬<齓仸<瓭'硥'搘褣菦讌%ァ墠.硁々)i; 8譴3誏S"&聾c1瓃(S>0滵Q絔 優]醓3U焣桜韍 "閜i脩!)廈脋ioS笰階譍I鞟S墫酇)眝醗Q稧#顯薊K骬Q=a晐>o盋Y8u梟+蚼Q汸 體!9?[7貼鐌!塷稬?.璒隕塛 漼_37雔譌_丒#鸙臘Q*噀,0!2峩S岴W筙 +絃w汥9a>錊S6遧k祅"! 窇 鯙 $雭o雖7#荙藬﹥沎峇 +僊菒(盵礷峑-閈⿴計亁(墮烰7儙賰勘暴硓薘乼變=塒籐賊=&87 媎訆W# .烶噽 鵣 ?鉑">厔 +<"廍$縔螮#6#7+鮌 #5嘑=*輡(絫説> , 礎橯!4 +镻 &%璸/ + 譍 塇嘨w# 逨摕醢 *7>9 %""虰檘9梋"沷7$蒟叕玽 #砡 4鵴0 !輑儎丅峾(蛒4"33談梀旴璠'丵!鵍+錬(烶鹒談4齯馦5媬罵4踃6=嚁軵絓璚,峇穃蓌誝蒕罦鸍晱 +蚢 昢&)遃;鸏3昦($,锳: 匑烠 # +氡—彸6:爪崒嫚梪匼縃-醽褃*穙&褍摓賹 荧锊贋.遼菬璣銟僀 亭?緻7'澂竣蟞(潐藣醫觽亼 +裃貯 厐%鹴 4玦塋烸骯郦貹鮌舖慣*蚈螦踋'$ 臞遠 僜7/鱝藠卙慟8>镋 颲$罧鰼: +橦峚硋7肕譧蚢鵐臜>乺錥 ;砢鲙6醖&怜"< ?U%!󂍭a!e慉# +*稩_:蒨鵪场齁嫈>泀蠆漄 踾丏4罷覺藙誸> +銁鱒嗓譤跙駒獶眰蚿嫥薽*乾 +J玚瓖龤蜄%焈瘡.駴賆媑/4匰 菒!鸝&颳 隩 裮彥醂>儀彣5鬄1鶆S搯檙晳?ヾ 蟟龝〥>酅潝蓋3 !#*0";U袾=仌 / 貯 軿* + + +駆,9'旲g輲裖塉M砆c 鹲:!彵縞.37S8昩 錼釥 +单乶臚*+乼# 8-鐍 睄硙醐转亯揺O";噑'羆檆錦岲諝&鉇<臝&6塲晆:'螈#盕珄水爪虳=觍輞揅2 籰 +3沝侑齉.弮眔铆  齶  荓  +鯒, 檞 +漲錏)鏽桾0紷厇焍薈 ?晀瘓眡褏藒痑?軮籱"玗譊a麗旽岾8㏄48臔 蛫褨6桹莄8.誒載隖橠8絠 絧!盄褮泂&韤 "仦閰癞9釂窇 遪 +筃、#鲌*韀骍)烣鱨繋恁= 搄!稺軾住蚲4駀馡5蒧鲿 乄彃)崲 櫁艆酼眖銜$補 $晧搱&蹟噦饯覨鏒龢鉌崜,輁櫏慻2乑鳡讃揊*%絿(廲 鼳>&塮??誁(酑筎0'逥(*噁亁%雑厁(〡-臡┅'讱噅踸棷誑7 矪7鳈 齙蚎鐠-/ : 珇 頀#鳜舝(53鹐% 嘵;晎┇硾 弰5籹疈+/褔璦汥誼墹 僶=輓4炸9﹉ Y5郓譺媋霃僠吵鱧#涧 肗 +L醠㎡療$檨廳懍卶9筣6憱鶋)鯛罖 +酙== 賝 !!觧眔98%Q+馝9# 僀! %+#&鉘 +<75獶'$+貮0 ?q"  (7!0茾%璏'03# (隞=9 鵨彌 盡 +#'瑻3;汚 礚0 鵪2?!5+慟 荳譚")8 "鱀4?! 跩/逥鞹!(%蟕 籬( +檷逺 )9 ."=-# ,桵 塁% *!< +"񙘸棥%<誏9&/$6< +璍*5!8 )+ &:!虭#!桜% +"裃焇4濉<5sm(蟁[蠘e罞漁齚4e?# a鰿墧'c憕慠>/&g墜魽I馼棯%[>:紾4<韎絘 +E絰c韸 u烞薞棰5#鉿洸 卪荿 o葽桜;5岴?;&韝疟覤螮!;璯*痽+籆m7褷岯;:" 働'盧e=軥烶薺ek僤軹 >鉘󠉩_>薚I7籛 亾08W#滿塜觘璂1丏v賮鐩髈? 韓n? 茿橤螦薃!顰盦匩o絍絍=4U9錫雤檏8峈' +鍑 +馳"*0笯 A軮:4" =07廠賖/2>)+?&禇+閎) (.: 乢媋 鵝8) &遀蒅)遉,:􅅩莈)踗)閎1K)鸇&貴' 玚4鵯_鶒Y蛽s釃 +桸W 昛+ 梋5鐦昋Q 弮'0塂瘖薔 +絥鞾 +%#*'0# . 9;??籆:0+8$譆瓌跧蚥 1烵:酘嘕貹'嘒蟆?盓 錓! 匼刹,揈霕;#踑鞽*#錕 +羨9=贸肂璚9鮅#薆賁昺$"&;!蚛 !颰稦 +砊&:6 卆#' 誆-  9(慡 )韐"?1(荂'"򊁡"0 "=#嘆(鹢i  1?7塊 K= 縄檁%8袿義 .嘺!2譔莇軱褯砶2,譧馧脪 荪g弡e慫鱋覰岴>7g憦/6轂砍縙 賐a9 弲 颱霋/彊難厈 17:+ 邭 +=#羱蹕鞼  e 9(;費 Z%諕態 鱻"7菕𙴎乮# ;4粯 針 卽4賤5揈8櫂 +蟸'軭7 +煇!髴2鵏砛酻蹣  籸񌸤88貺訏筍j# 3(絚誏!-񆻿焳4諄 飼4#馷詹祘厎5 >覯絢4c盄聿閇7 +?譠裐跲? %4颻I;眿,8 S7#!遡$[--*"”$匒󍨃貸]噵7U袹c$> 8m)󳕄8! a﹑ $[鵯]疉锳e#Y9 6廇i[ 漲5罝"#"q齶弌 c駑蒩,玹烡97僴8塁W6蹗S6峎S9錬 S?閙廌/[籐!&1(2 !換!I韇鸝8跩9裦10&筏鵼7G [ + g%汚 箎(筨颿!;!"儼g婲a!渐   綉珯a7鶘莃羍e #"? +5g乍丣 礘錋]#駎!譿 9c缨#穥_卪漮鸘 +M珦峮誰薩S$;+韝/祴_ 0u漄!/8O(?W$懇蟦W蛗-橜 +6k9/ 莢慬i?,筺蛨箰佗s 穄筬i 8飻/蚖 墷9q!!鏸 Q#S +7盤(阀睈 籅8i 鶗稲S賛 1a +8漒翞 箙 噆5%/廕 梒酈 :6 #W焟'鐟 邟遷a# 齫箤%!裃k┎玣#Y獽扫窉媔単# .晉-.$,e鳢񘜐鳍噽8 9o堪嫏7廣7崰鱦8 橞-K獿荳 !檼 +仈+飡S;鮦嘦 ]拽僝匸6 +臸焄m9沴, m鲊, o峚飃鱩嘍W煄賘慶 +髚錙褎M鐅2%_6=𨢃莟痡鵦縅W鳛儌rA#-  8" w絤閊!'6絼鳒麉 o"S慒2"k儁;!#K5#?譵Q" 8 ;踐5 ] +M璠!%k7塏/丼蹜蒫逨K 峞粄a傾]7鯀艞U-菃1綌廡;!禑卋7 W協 誸c 痝脇 + &舖_虎 憀!焏揨? 褝 q_a"鐉絹跕6岶! 话骽 :]媴 3:_穬鞮$U 痠"m﹝U輖跢誅 +暕 粐Q薵#")Go#彃#"瘜( a絯Y霗賡><"飺6;鉋U8 m晳絪驚8_棆鳉+揬k穀稟O鳏粂8Qy鼳7$亇肁  /< '飏橫 1g$盢$璲0,"9  隦45 鼵6廙驞" + 闋:摣4痩1飊胢7綇/羘鯑籓壊(閨=!.幛 薟乷.螿摝廱%鮝; +0鱏( ((! 8昈"痯,(旹廟罻賂藯8#.韘1%%礢1&儞穁鳚揬齲*焀繃飪!⿸馚゛褈疭訙絙弧褕蛺仛鏜焺範興篆飉鏛菂9 +-'鍤3蠠&蛢憇檶噏蛈璉誱<覽焠 骩7觰>嫂禂顯潳/"廼汵?覢 :7 +齬 讔輀6 $輒 !>8臰沞9>85>: 慍5縎#蓂"搒''u/"4!9_?"鵓Y艊Y焜 ,!賍-58( W裭檡[7摂滽衰k訒鮼匬!閑藪互慯 駂0縠 讞穎 +8Y +賜 馰 = :鉉 +荖蒳"駗( 6組7髕繗 脝 貽!蚘5僊 !睊 !7穕 機9 ! 鼸7崍$廎97慛83絅#莑橩7隺 ,鱜 遖  +9;9弡昛#砨8< +慙5隲 漨!0 舋慡 盬 梍K "7?齋闀暋祵0鸇/&6"覭+%#雗 +$丵 紾 +!;梺薉罞G蒰$#%+"莏" 鮻 飹鵃 痏匨檢89彃籩顰彠丟;賎"嫙 +繐螷7)褁閍>韕"鏥 藧颶,瘵舚"$ 閼&亃6笰 М藘a8E铯蛣"1%觷韄馛:=悒瓀棥蟔-(!$旾73!开藖麪〩盽鐧.雪貵漚麔+蟻彯訛 +<遅硹,卻桟馱1檜-肧婳鵆邏荾焒!鮥漡骎'!)5焞諠蹜#罭专6嘦#4箎4跴銞裛 噊厧 譐 楷駃 搎踲 :报璒颪讀*隮7誆2&羳鯂閖4脄釚;怒荈譝%璮郗9鏐莳蒼齝鵾壆 2Y*釘&Y鹠縂浓 ?焤W鸐潻焝U#梠┍Q璴&Y讐蟄崁c婮棟o葾摔縫麛'縪墸骾僛&煗羑+縹k慘俨晊絉瘱顳袸1-;懑:1伇6壂u齴酰c򃱘#O泞慐厸-薉)稢$ 蠇飾髷3筦籺鍡潉5莶﹕5.薸/焪蟌鼲/>颽;9 揓59󸀋w3 +筊﹖2=%瓬;損)# &? 9荹鸑鮎墂7棸暔闃麞=5嘲; +睈裩 +礦焾讔媉丮,輗粰 痟韺丱画鮺".砄"鬁誗 僘>玂馟脦桳繆鮎憍螹輰雊祳瓍墴痸箰璄悻"%焎%񱙤輒逤 嘇鏫軱鞰公蚞7髥洊沢 蛒鶢P 珨5觓眥&񑑦 薧齮6慞艩$#煶3粣9珱1:獻 進觻!頌誳6眐 祇 c 烪Q匸0 +9{) 玨議 +E9 _,!馯 +5Y9g縨酓(8+$*蒃a" +祕蓳禋!'c昛#7:1#閏"卭 +鉊!f櫒-"臞 9 譆$"(軵$ +8% :򊰔 <盄$99#/)#蒓' 颪< 鸄%"(譒"4?3 譊+$6譴 +'紺 : )滼髄 7鮂 +跴>* 6 +4?4)9媟 8%#(8稝 +镺4>搑"塃. &!疪鏷"遪 烰!裀珌0贰嘪隕韹9晐洤1彑莕 7>鸏*/"縘 + 6誵蒄 +I噿"#峔0遌9塪廦 鬂峼!訏g(讄岵羃&駸汭3 3 &臟盰 錠򄬊驣+"懏)濂愆軴眂讒 +搇"*胅儤賔檓6'儂蓇肸媭逧 憟7齂梱蟋%盨&製%婨覩馭 ,㎏羪02礑9c鉝舎' 5跘9% 335  *蹨﹎厵漗1s&7薊 3莬 '. 3髲莠U#!齷翂"輩 5!?粡鍊 eゝ蒁塅9-姜9踾’ 6Q綀<肞壉-雟痻稴> !򵍣<> #璂嘗貽 ;6縌 :) 絖;媖 <誃85锳; 紻鏏誂荓3袴 8! 袲*:3!89鸊齁鵒#*緼 ,镻璖3 +r 胓!隬鱴"醳綈 噀銟亀焫!儫崺 :飵# 釤9胇6舲3廚:噽缨蒏颻烻!崼踆7箵7 颎"0鮆6諊伲橴瓧獺"澃恝⿹弓塟揂'&蛦#$艌鏺+搝&龍觸舘4崪軰 玤3穒雈脭=髒) 賳&橪雸揘6 +! #卻>"籗A</銄*矷蒦誠檡3璿 ;漀 + 櫐!"8,0 菚岐峼-漬譆 +楝:鐘 儅痚 墱鉯餃踥&8&遻隣踇-閛 +.<梚遲q璪/ +罶鶈'諂霜購6檊媅丄肎跘盽8閥馤薟7廟 鶄﹦1+岴璱4跾汫僕昇橰絈盡-駙6門&開 +譙"齝慮軼鮐6匞 鼺=('#紻硔儖鐉 瘯<鮡%贉桭&跘)4*塷誂搊 鶓 閞鯅匨!輠蹨*紷艑跲袲񙎦N5蟸誜3笵'痆砮"噓蓱驠礑"彅袬蟅#龐鲍=睎盫息1攉礽0錛0瘛鞺袮  鐉1橨 +稝篃󙋱諘骫齦 +儂= +裿驟 邟乫: 璭峼?虷s!廣覥6鮶 8 韓8檝## 旸!搥*&&婭0慹/觨#蜆3 邨 7盋誰6祪9雡!潠 +螸 " +﹖!蟨(顯8+30&$%#'廐%3玔:璟滰硚/&)鵓&=! 疪0 &=) 搷 򄐝1 !#仚$!'%0 &( *,鵍&(  > !+=% +  蟵伆B!8*廣&獸廆誨6貿y8539%+罙4??9穂8)镋,3 !i9慴57跾>-/嚠絆璏18漄;%:8"9 +8*,籄* +疪 $􅶝 +0慓<:4!:0 4("0 軯"4#"󸘵遖!肞,緼 9顱0󚁄!*+6<塀 驩鏐!潱')峵)乀-誤-97<$ +粇 嫅蒰$羠嵅暢玓僇 <飮2 +韷4慗骵4-錊蟜,軳;:颼筽﹝悃盉蛜礬丮慭讄軪. 觃?%慣絸髣脴=憡飍鏘鐚摑婦A2嘗!6A鞡G〢 滸 貶)C(o籑!0稦e);8u+a +6*+8鱝Ug゛0$"!]顳q媟8遉96 鸉Y5[.#?-O!%*%媙 +c婸!C*!")覰k( + O+慒m6,W緼#c!隸$紸K*%7;鞟+󟷣sk稤璔媟w o!4M6  2臥' +6I驠y!%;2!"鮍 飈 񰳇Y). 3_烝9("Y>噏i #疉,璛k 7%#O &汮:!:#u󹂡e.6" 骮邁?5Q=#'鮠2+c#76誴!A%瑼7W!+WU ":U/0?;=; 峃+e 7僔W8肊e!‘9繕軵粙媟鮑誌#鵮8駩籫 +璵/ 縿儊蟁條硻亖"崓塗煂b踍藇 塿%!)匛"賦3 褌焌") 脨#7覲.鹹+鹟 鵦旳臗2( "#2粻オ!蹧昦 峆? 4 +$ # +3<3:8U沨 <弉 =! 粈> 峍蚚礚,6鱎矛 儬莍揂+(q藚飹綅%#痗7>箷5誑荱塱遾褳:? +U蔀m丒- ).8 +;(籌86#馧籝 3񫭍0覫銕 9(0盩 +軶1 + 铅莖3 4?%颴#銒鮱/"閯蠁 +$鍇廯/粡#乁%閭*C)彂+ ) 韃!O飹?$ 7檣8 玘譑 $醳7 +.昪7亀縆0 韑' +薠)!*雥骲9'錤!."罜  螰 鐓臛7檌 煔 ; 3 珆! 8噚7 覾 鹸8!梲繎99檚"棙 稥.7砙7搢! E򢘵!=8遹#鞳!祶&7笹M6稸! $璪1鉞鶕?.肣#&# 6檄"6賋觛"齒廠;驪$? 򈍏>(/9骦+!蓻[& < 賏籖鞬0鏲!乬亗$廮"<  鱞盚輝漁 +鵟"龓 !6駱虲絑薵 )鞵憹! *鵍. (/鱆齣  !6$(%*跭:$<%0 艖 + *薍醙#艕鵎  瘂蒰颪%誘 # +m +*輓 E4%:裡 : $疦,嘊'"9"髸)緽; !塉7<齵 薻葽虵譓#颵嘖.C":,##5習7'%慚𔀼軻;褭鸌(#5塏 .'骙9匳 +酦3貼?誐%稡罖舥."ー= 逧. +慐 2閜卲諡 沨><17慳丳-? +颷髿烼鶀%8 )9:髏説穔蹆=3墪" 7* *5薕袮%虶# 9( ( 9 >#.7 8悱絅 '"9譧噿 +5 +1 6% 盡" / 橭$61"#&2 #!#(#("" &籋 7$ #! 󎡞 (#荄,# #"- 0 "(4.99%0!_?籏橾1鐆蓷潰Y玝肑瓨僒怼僴硹 +峢k時!罼5僩虸t(厠!4*{e80-0 鸻&3-(錠揢 񼂳*&/>"鲌僗,%!1鱌絙( 81,"0稱- 4 1+ 隒 0=6晵𓵚"#軵羅镈/򉸮 +-粇  塨璤1 鞼& 驟:(#隞 "'/&*) ( 酔3價讗譣厇粦穖!!鱟}<僜 乄 1螷=1 ("1颙罬$%匫荁睡=儘玥麙揤鵶玨#雙/釛諎焁2鸎򨌽獵錑臚菒;?臕9]袵%3":; : ( #錞"橬<"蟖) 8儧' 6 +'( "莔婰9 +!=霅¦覶漋焁荄锧2!+"$貹卼:$<=5)"+軦6>鉋烱 祍3羫鉩/ ::' 2 +08輢!璲&錎 厏 鞪#*韋5\ +4桪/:?駇G "%,-旻$?8誦8-昉 655: !/僶舼򺄞3C馜G񌣯. 1匯 長. 8舚78 48鍕゜貮稫袮¦窉#/>"/7 +#荅+ ?1K 6"Q%工塙:->馻託龍撷&+ +%)螦虯 !1礍誐&笯>9 %/O廆#3<婣%/箁--廋蚚)髍2>.虳(&#跡3羀:,檭瓉77:盙8鹻":=%烥7 ?<񆎘%# 8 !泋%莥颮〩璊塏 0 +稨鏞c匧!# +󀶸= +!)󥾳摎駐薬<齓仸<瓭'硥'搘褣菦讌%ァ墠.硁々)i; 8譴3誏S"&聾c1瓃(S>0滵Q絔 優]醓3U焣桜韍 "閜i脩!)廈脋ioS笰階譍I鞟S墫酇)眝醗Q稧#顯薊K骬Q=a晐>o盋Y8u梟+蚼Q汸 體!9?[7貼鐌!塷稬?.璒隕塛 漼_37雔譌_丒#鸙臘Q*噀,0!2峩S岴W筙 +絃w汥9a>錊S6遧k祅"! 窇 鯙 $雭o雖7#荙藬﹥沎峇 +僊菒(盵礷峑-閈⿴計亁(墮烰7儙賰勘暴硓薘乼變=塒籐賊=&87 媎訆W# .烶噽 鵣 ?鉑">厔 +<"廍$縔螮#6#7+鮌 #5嘑=*輡(絫説> , 礎橯!4 +镻 &%璸/ + 譍 塇嘨w# 逨摕醢 *7>9 %""虰檘9梋"沷7$蒟叕玽 #砡 4鵴0 !輑儎丅峾(蛒4"33談梀旴璠'丵!鵍+錬(烶鹒談4齯馦5媬罵4踃6=嚁軵絓璚,峇穃蓌誝蒕罦鸍晱 +蚢 昢&)遃;鸏3昦($,锳: 匑烠 # +氡—彸6:爪崒嫚梪匼縃-醽褃*穙&褍摓賹 荧锊贋.遼菬璣銟僀 亭?緻7'澂竣蟞(潐藣醫觽亼 +裃貯 厐%鹴 4玦塋烸骯郦貹鮌舖慣*蚈螦踋'$ 臞遠 僜7/鱝藠卙慟8>镋 颲$罧鰼: +橦峚硋7肕譧蚢鵐臜>乺錥 ;砢鲙6醖&怜"< ?U%!󂍭a!e慉# +*稩_:蒨鵪场齁嫈>泀蠆漄 踾丏4罷覺藙誸> +銁鱒嗓譤跙駒獶眰蚿嫥薽*乾 +J玚瓖龤蜄%焈瘡.駴賆媑/4匰 菒!鸝&颳 隩 裮彥醂>儀彣5鬄1鶆S搯檙晳?ヾ 蟟龝〥>酅潝蓋3 !#*0";U袾=仌 / 貯 軿* + + +駆,9'旲g輲裖塉M砆c 鹲:!彵縞.37S8昩 錼釥 +单乶臚*+乼# 8-鐍 睄硙醐转亯揺O";噑'羆檆錦岲諝&鉇<臝&6塲晆:'螈#盕珄水爪虳=觍輞揅2 籰 +3沝侑齉.弮眔铆  齶  荓  +鯒, 檞 +漲錏)鏽桾0紷厇焍薈 ?晀瘓眡褏藒痑?軮籱"玗譊a麗旽岾8㏄48臔 蛫褨6桹莄8.誒載隖橠8絠 絧!盄褮泂&韤 "仦閰癞9釂窇 遪 +筃、#鲌*韀骍)烣鱨繋恁= 搄!稺軾住蚲4駀馡5蒧鲿 乄彃)崲 櫁艆酼眖銜$補 $晧搱&蹟噦饯覨鏒龢鉌崜,輁櫏慻2乑鳡讃揊*%絿(廲 鼳>&塮??誁(酑筎0'逥(*噁亁%雑厁(〡-臡┅'讱噅踸棷誑7 矪7鳈 齙蚎鐠-/ : 珇 頀#鳜舝(53鹐% 嘵;晎┇硾 弰5籹疈+/褔璦汥誼墹 僶=輓4炸9﹉ Y5郓譺媋霃僠吵鱧#涧 肗 +L醠㎡療$檨廳懍卶9筣6憱鶋)鯛罖 +酙== 賝 !!觧眔98%Q+馝9# 僀! %+#&鉘 +<75獶'$+貮0 ?q"  (7!0茾%璏'03# (隞=9 鵨彌 盡 +#'瑻3;汚 礚0 鵪2?!5+慟 荳譚")8 "鱀4?! 跩/逥鞹!(%蟕 籬( +檷逺 )9 ."=-# ,桵 塁% *!< +"񙘸棥%<誏9&/$6< +璍*5!8 )+ &:!虭#!桜% +"裃焇4濉<5sm(蟁[蠘e罞漁齚4e?# a鰿墧'c憕慠>/&g墜魽I馼棯%[>:紾4<韎絘 +E絰c韸 u烞薞棰5#鉿洸 卪荿 o葽桜;5岴?;&韝疟覤螮!;璯*痽+籆m7褷岯;:" 働'盧e=軥烶薺ek僤軹 >鉘󠉩_>薚I7籛 亾08W#滿塜觘璂1丏v賮鐩髈? 韓n? 茿橤螦薃!顰盦匩o絍絍=4U9錫雤檏8峈' +鍑 +馳"*0笯 A軮:4" =07廠賖/2>)+?&禇+閎) (.: 乢媋 鵝8) &遀蒅)遉,:􅅩莈)踗)閎1K)鸇&貴' 玚4鵯_鶒Y蛽s釃 +桸W 昛+ 梋5鐦昋Q 弮'0塂瘖薔 +絥鞾 +%#*'0# . 9;??籆:0+8$譆瓌跧蚥 1烵:酘嘕貹'嘒蟆?盓 錓! 匼刹,揈霕;#踑鞽*#錕 +羨9=贸肂璚9鮅#薆賁昺$"&;!蚛 !颰稦 +砊&:6 卆#' 誆-  9(慡 )韐"?1(荂'"򊁡"0 "=#嘆(鹢i  1?7塊 K= 縄檁%8袿義 .嘺!2譔莇軱褯砶2,譧馧脪 荪g弡e慫鱋覰岴>7g憦/6轂砍縙 賐a9 弲 颱霋/彊難厈 17:+ 邭 +=#羱蹕鞼  e 9(;費 Z%諕態 鱻"7菕𙴎乮# ;4粯 針 卽4賤5揈8櫂 +蟸'軭7 +煇!髴2鵏砛酻蹣  籸񌸤88貺訏筍j# 3(絚誏!-񆻿焳4諄 飼4#馷詹祘厎5 >覯絢4c盄聿閇7 +?譠裐跲? %4颻I;眿,8 S7#!遡$[--*"”$匒󍨃貸]噵7U袹c$> 8m)󳕄8! a﹑ $[鵯]疉锳e#Y9 6廇i[ 漲5罝"#"q齶弌 c駑蒩,玹烡9塁W6蹗S6峎S9錬 S?閙廌/[籐!&1(2 !換!I韇鸝8跩9裦10&筏鵼7G [ + g%汚 箎(筨颿!;!"儼g婲a!渐   綉珯a7鶘莃羍e #"? +5g乍丣 礘錋]#駎!譿 9c缨#穥_卪漮鸘 +M珦峮誰薩S$;+韝/祴_ 0u漄!/8O(?W$懇蟦W蛗-橜 +6k9/ 莢慬i?,筺蛨箰佗s 穄筬i 8飻/蚖 墷9q!!鏸 Q#S +7盤(阀睈 籅8i 鶗稲S賛 1a +8漒翞 箙 噆5%/廕 梒酈 :6 #W焟'鐟 邟遷a# 齫箤%!裃k┎玣#Y獽扫窉媔単# .晉-.$,e鳢񘜐鳍噽8 9o堪嫏7廣7崰鱦8 橞-K獿荳 !檼 +仈+飡S;鮦嘦 ]拽僝匸6 +臸焄m9沴, m鲊, o峚飃鱩嘍W煄賘慶 +髚錙褎M鐅2%_6=𨢃莟痡鵦縅W鳛儌rA#-  8" w絤閊!'6絼鳒麉 o"S慒2"k儁;!#K5#?譵Q" 8 ;踐5 ] +M璠!%k7塏/丼蹜蒫逨K 峞粄a傾]7鯀艞U-綌廡;!禑卋7 W協 誸c 痝脇 + &舖_虎 憀!焏揨? 褝 q_a"鐉絹跕6岶! 话骽 :]媴 3:_穬鞮$U 痠"m﹝U輖跢誅 +暕 粐Q薵#")Go#彃#"瘜( a絯Y霗賡><"飺6;鉋U8 m晳絪驚8_棆鳉+揬k穀稟O鳏粂8Qy鼳7$亇肁  /< '飏橫 1g$盢$璲0,"9  隦45 鼵6廙驞" + 闋:摣4痩1飊胢7綇/羘鯑籓壊(閨=!.幛 薟乷.螿摝廱%鮝; +0鱏( ((! 8昈"痯,(旹廟罻賂藯1%%礢1&儞穁鳚揬齲*焀繃飪!⿸馚゛褈疭訙絙弧褕蛺仛鏜焺範興篆飉鏛菂9 +-'鍤3蠠&蛢憇檶噏蛈璉誱<覽焠 骩7觰>嫂禂顯潳/"廼汵?覢 :7 +齬 讔輀6 $輒 !>8臰沞9>85>: 慍5縎#蓂"搒''u/"4!9_?"鵓Y艊Y焜 ,!賍-58( W裭檡[7摂滽衰k訒鮼匬!閑藪互慯 駂0縠 讞穎 +8Y +賜 馰 = :鉉 +荖蒳"駗( 6組7髕繗 脝 貽!蚘5僊 !睊 !7穕 機9 ! 鼸7崍$廎97慛83絅#莑橩7隺 ,鱜 遖  +9;9弡昛#砨8< +慙5隲 漨!0 舋慡 盬 梍K "7?齋闀暋祵0鸇/&6"覭+%#雗 +$丵 紾 +!;梺薉罞G蒰$#%+"莏" 鮻 飹鵃 痏匨檢89彃籩顰彠丟;賎"嫙 +繐螷7)褁閍>韕"鏥 藧颶,瘵舚"$ 閼&亃6笰 М藘a8E铯蛣"1%觷韄馛:=悒瓀棥蟔-(!$旾73!开藖麪〩盽鐧.雪貵漚麔+蟻彯訛 +<遅硹,卻桟馱1檜-肧婳鵆邏荾焒!鮥漡骎'!)5焞諠蹜#罭专6嘦#4箎4跴銞裛 噊厧 譐 楷駃 搎踲 :报璒颪讀*隮7誆2&羳鯂閖4脄釚;怒荈譝%璮郗9鏐莳蒼齝鵾壆 2Y*釘&Y鹠縂浓 ?焤W鸐潻焝U#梠┍Q璴&Y讐蟄崁c婮棟o葾摔縫麛'縪墸骾僛&煗羑+縹k慘俨晊絉瘱顳袸1-;懑:1伇6壂u齴酰c򃱘#O泞慐厸-薉)稢$ 蠇飾髷3筦籺鍡潉5莶﹕5.薸/焪蟌鼲/>颽;9 揓59󸀋w3 +筊﹖2=%瓬;損)# &? 9荹鸑鮎墂7棸暔闃麞=5嘲; +睈裩 +礦焾讔媉丮,輗粰 痟韺丱画鮺".砄"鬁誗 僘>玂馟脦桳繆鮎憍螹輰雊祳瓍墴痸箰璄悻"%焎%񱙤輒逤 嘇鏫軱鞰公蚞7髥洊沢 蛒鶢P 珨5觓眥&񑑦 薧齮6慞艩$#煶3粣9珱1:獻 進觻!頌誳6眐 祇 c 烪Q匸0 +9{) 玨議 +E9 _,!馯 +5Y9g縨酓(8+$*蒃a" +祕蓳禋!'c昛#7:1#閏"卭 +鉊!f櫒-"臞 9 譆$"(軵$ +8% :򊰔 <盄$99#/)#蒓' 颪< 鸄%"(譒"4?3 譊+$6譴 +'紺 : )滼髄 7鮂 +跴>* 6 +4?4)9媟 8%#(8稝 +镺4>搑"塃. &!疪鏷"遪 烰!裀珌0贰嘪隕韹9晐洤1彑莕 7>鸏*/"縘 + 6誵蒄 +I噿"#峔0遌9塪廦 鬂峼!訏g(讄岵羃&駸汭3 3 &臟盰 錠򄬊驣+"懏)濂愆軴眂讒 +搇"*胅儤賔檓6'儂蓇肸媭逧 憟7齂梱蟋%盨&製%婨覩馭 ㎏羪02礑9c鉝舎' 5跘9% 335  *蹨﹎厵漗1s&7薊 3莬 '. 3髲莠U#!齷翂"輩 5!?粡鍊 eゝ蒁塅9-姜9踾’ 6Q綀<肞壉-雟痻稴> !򵍣<> #璂嘗貽 ;6縌 :) 絖;媖 <誃85锳; 紻鏏誂荓3袴 8! 袲*:3!89鸊齁鵒#*緼 ,镻璖3 +r 胓!隬鱴"醳綈 噀銟亀焫!儫崺 :飵# 釤9胇6舲3廚:噽缨蒏颻烻!崼踆7箵7 颎"0鮆6諊伲橴瓧獺"澃恝⿹弓塟揂'&蛦#$艌鏺+搝&龍觸舘4崪軰 玤3穒雈脭=髒) 賳&橪雸揘6 +! #卻>"籗A</銄*矷蒦誠檡3璿 ;漀 + 櫐!"8,0 菚岐峼-漬譆 +楝:鐘 儅痚 墱鉯餃踥&8&遻隣踇-閛 +.<梚遲q璪/ +罶鶈'諂霜購6檊媅丄肎跘盽8閥馤薟7廟 鶄﹦1+岴璱4跾汫僕昇橰絈盡-駙6門&開 +譙"齝慮軼鮐6匞 鼺=('#紻硔儖鐉 瘯<鮡%贉桭&跘)4*塷誂搊 鶓 閞藲鯅匨!輠蹨*紷艑跲袲񙎦N5蟸誜3笵'痆砮"噓蓱驠礑"彅袬蟅#龐鲍=睎盫息1攉礽0錛0瘛鞺袮  鐉1橨 +稝篃󙋱諘骫齦 +儂= +裿驟 邟乫: 璭峼?虷s!廣覥6鮶 8 韓8檝## 旸!搥*&&婭0慹/觨#蜆3 邨 7盋誰6祪9雡!潠 +螸 " +﹖!蟨(顯8+30&$%#'廐%3玔:璟滰硚/&)鵓&=! 疪0 &=) 搷 򄐝1 !#仚$!'%0 &( *,鵍&(  > !+=% +  蟵伆B!8*廣&獸廆眡褏藒揃羗痑?籱"玗譊a麗%旽岾8㏄8臔褨媞 6桹'莄8.誒載隖橠8絠 絧!盄褮&韤 "仦閰癞9釂窇 鵗%漅菧闂醥遪 +筃、﹣鞶#鲌*韀骍)烣鱨繋恁= 搄!稺軾住蚲4駀馡5蒧鲿 乄彃)崲櫁艆酼眖銜$補 $晧搱&蹟噦饯覨崗;鏒龢鉌崜,輁櫏慻2乑鳡讃揊*%絿(廲 鼳>&塮??誁(酑筎0'逥(*噁亁%雑厁(〡-橮洂彋臡┅'讱踸棷誑鏦7 嫲岖矪7鳈 蚎鐠-/ 弇" : 珇%齳盨!269 頀揑8#鳜舝(53鹐% 嘵;晎┇硾 弰5> 籹媍疈墑+/!褔璦汥誼墹 僶邸蒕鶉=輓4炸9﹉ Y5郓譺媋霃僠吵鱧#涧 肗 +L醠㎡療$檨廳懍卶9筣6憱晹鶋)罖 +酙== 賝 !!觧眔98%Q+馝9# 僀! %+#&鉘 +<75獶'$+貮0 ?q"  (7!0茾%"璏'03# (隞=9 鵨彌 盡 +#';汚 礚0 鵪2?!5+慟 荳譚")8 "鱀4?!)鸆 跩/逥鞹!(%蟕 籬( +檷逺 )9 ."=-# ,桵 塁% *!< +"񙘸棥%<誏9&/$6< +璍*5!8 )+ &:!虭#!桜% +"裃焇46;g濉<5sm(蟁[蠘e罞漁齚4e?# a鰿墧'c憕慠>/&g墜魽I馼棯%[>:紾4<韎絘 +E絰c韸 u烞薞鵔鏎]棰5#鉿洸 卪荿 o葽桜;5岴?;&韝箘? 輈疟覤螮!;璯*痽+籆m7褷" 働'盧e=軥烶薺ek僤軹 >鉘艅󠉩_>薚I7籛 亾;鏣憿08W#滿塜觘璂1丏v賮鐩髈? 韓n? 茿橤螦薃!顰盦匩o絍絍=4U9錫雤檏8峈' +鍑 +馳"*0笯 A軮:4" =07廠賖/2>)+?&禇+閎) (.: 乢-媋 鵝8) &遀蒅)遉,:􅅩莈)踗)閎1K)鸇&貴' 玚4鵯_鶒Y蛽s釃 +桸W 昛+ 梋5鐦昋Q 弮'0塂瘖薔 +絥鞾 +%#*'0# . 9;??籆:0+8$譆瓌跧蚥 1烵:酘嘕貹'嘒蟆?盓 錓! 匼刹,揈霕;#踑鞽*#錕 +羨9=贸肂璚9鮅#薆賁昺$"&;!蚛 !颰稦 +砊&:6 卆#' 慦誆-  9(滲4慡 )韐"?1(荂+'"򊁡"0 "=%廘箶#嘆(鹢i  1?7塊 K= 縄檁%8袿義 .嘺!2譔莇軱褯砶2,譧馧脪 荪g弡e慫鱋覰岴>7g憦/6轂砍縙 賐a9 弲 颱霋/彊難厈 17:+ 邭 +=#羱蹕鞼  e 9(;費 Z%諕態 鱻"7菕𙴎乮# ;4粯 針 卽4賤5揈8櫂 +蟸'軭7 +煇!髴2鵏砛酻蹣  088貺訏筍j# 3(絚誏!-񆻿焳򦽘4諄 飼4#馷詹祘厎5 >覯絢4c盄聿閇7 +?譠裐跲? %4颻I;眿,8 S "齪O7#!A厫遡$[搎--*"7 +”$匒󍨃貸]噵7U袹c$> 8m)󳕄8! a﹑9k閐 $[鵯]疉锳e#Y9 誥! +6廇i沵 +e[ 粄 ";漲5罝"#"q齶弌 c駑蒩,玹烡9齩S塁W6蹗S6峎S9錬 S?閙廌/[籐!&1(2# !換!I韇鸝8跩弴9裦10&筏鵼7G [ + g%汚 箎(筨颿!;!"儼g婲a!渐   綉珯a7鶘莃羍e婽 #"? +5g乍丣 礘錋]#駎!譿缨#穥_卪漮鸘 +M珦峮誰薩S$;+韝/祴_ 0u漄!/8O(?W$懇蟦W蛗-橜 +6k9/ 莢漑慬i?,筺蛨箰佗s 穄莮筬i 8飻/蚖 墷9q!!鏸 Q#S +7讬U盤誣鯏(阀睈 0蒖a 籅8i 鶗稲S賛 1a +8漒翞 箙 擐噆5%/廕 梒酈 :6 #W焟'鐟 邟遷a# 齫箤%!裃k┎玣#Y獽扫窉媔単# .晉-.$,e5鳢񘜐鳍噽8 9o堪嫏7廣7崰鱦8 橞-K獿荳 !檼 +仈+飡S;鮦嘦 ]拽僝匸6 +8 _臸焄m9沴, m鲊, o峚飃鱩嘍W煄賘慶 +髚錙褎M鐅2%_6=𨢃莟痡鵦縅W鳛儌rA#-  8" w絤匶c閊!'6絼鳒麉 o"S慒2"k儁;!#K5#?譵Q" 8 ;踐5 ] +M璠!%k凯7塏/丼蹜蒫逨K 峞粄a傾]7鯀艞U-綌廡;!禑卋7 W協 誸c 痝脇 + &舖_虎 憀!)焏揨? 褝 q_a"鐉絹跕6岶! 话骽 :]媴 3:_穬鞮$U 痠"m﹝U輖跢誅 +暕 粐Q薵#")Go#彃#"瘜( a絯Y霗賡><"飺6(_鉋U8 m晳絪驚8_棆鳉+揬k穀稟O鳏粂8Qy鼳7$亇肁  /< '飏橫 1g鐃$盢$璲0,"9  隦45 鼵6廙驞" + 韈闋:摣4痩1飊彨胢7綇/羘鯑籓壊(閨!.幛 薟乷.螿摝鮝; +0鱏( ((! 8昈"痯 +醆3,(旹廟罻賂藯8#.韘1%%礢1&儞穁蒛鳚揬齲*焀繃飪!棄򵦞⿸馚゛褈疭訙絙弧褕蛺仛鏜範興飉鏛﹐菂9 +-'鍤3蠠&藦潊蛢鮓憇檶噏筆 蛈璻蟿璉誱<覽焠 丠骩7觰>嫂禂顯潳/"廼汵?覢 :7 +齬 讔輀6 $輒 !>8臰沞9>85>: 慍5縎#蓂"搒''u/"4!9_?"鵓Y艊Y焜 鶑",!賍-58( W裭檡[7摂)峼滽]褩胑 衰k訒鮼匬!閑藪互慯 駂0縠 讞穎 +8Y +V賜 馰 = :鉉 +硘厊荖蒳"駗玔"( 6組7髕梕酠繗 !脝 貽!蚘5僊 !睊 !7穕 機9 ! 邒#鼸7祑7崍$廎973絅#莑橩7隺 ,鱜 遖 9 +9;9昛#砨8< +慙5隲 漨!5鱱:0 舋慡 盬 梍K "7?齋褦闀暋祵鸇/&6"覭+%#雗 +/ 酑$丵 紾 +!;梺颋#鞞薉罞G蒰$漥!#%+"莏" 鮻玙痁  飹鵃 痏匨檢89彃籩顰!丟;賎"嫙7 +繐螷7)褁閍>瓃"韕"+#9鏥 藧9颶,瘵舚"$ 閼&亃蓆6&笰 М藘a8E铯蛣"1%觷韄馛:=悒瓀棥蟔-(!$旾73隚!开藖麪〩盽鐧.雪貵漚麔+蟻彯訛 +<遅硹,卻桟馱1檜-肧婳鵆邏荾焒!鮥漡骎'!)5焞諠蹜#蛃罭专6嘦#4箎4跴銞裛 噊厧 譐 楷駃 搎鵑匑#颷驦叢踲 :报璒颪讀*隮7誆2&羳鯂閖4脄釚癫;怒蠑祏>逹 譝%璮郗棁9鏐莳蒼齝鵾壆 2Y*釘&Y鹠縂浓 ?焤W鸐潻焝U#梠┍Q璴&Y讐蟄崁c婮棟o葾摔縫麛'縪墸骾僛&煗羑+縹k慘俨晊絉瘱隿顳袸1舕E#誮-;懑:1伇6壂u齴酰c򃱘#O泞慐厸-薉)稢$ 蠇飾髷3筦籺鍡潉5莶﹕5.薸/焪蟌鼲/>颽;9馾--m% 揓59󸀋w3 +筊#"#﹖2=%瓬;損)# &? 9鮎麞=;礦焾讔粰 痟韺丱画 +鮺".砄"鬁誗 僘>玂昡籓昺馟脦桳繆鮎憍螹輰雊祳瓍墴痸箰璄悻%逤 嘇 岺沢 蛒鶢P 珨5隌 進觓眥&񑑦 薧齮6慞艩$#煶3粣9蟂 (踦 進頌誳6眐 祇 c 烪Q匸 +9{) 玨議 +E9 _,!馯 +5Y9g縨酓(8+$*蒃a" +祕蓳!'c昛#7:1#閏"卭 +鉊!f櫒-"臞 9 譆$"(軵$ +8% :򊰔 <盄$99#/)#蒓' 颪< 鸄%"(譒"4?3 譊+$6C籊*7譴 +'紺 : )滼髄 7鮂 +跴>* 6A1 +4?4! ?誆񾆄 )9媟 8%#(8稝 +镺4>搑"塃. &!疪)馜"鏷"遪 烰!裀珌0贰嘪隕韹9晐洤1彑 7>鸏*"縘 + 6 +廈蓛 +9 瓔I噿蚒"#峔0&遌9塪廦 鬂峼?螥!㊣鹙訏g(讄岵羃&駸汭3 3 &臟盰 錠煋瓡 ; +6򄬊驣+"懏)濂愆軴眂讒 +搇"*胅儤賔檓6 '儂蓇肸媭逧 憟鄢7齂梱%盨&製%婨覩馭 遃羪02礑9c鉝舎' 5跘9珬 % 335  *1s&7薊 3莬 '. 3髲莠U#!齷翂"輩 5!?粡搳鍊 eゝ蒁塅9-姜9踾’ 6Q誂""綀<肞諅!壉-鱷5雟昞痻韰稴> !򵍣<> #璂嘗貽 ;6縌 :煍) 絖;媖 <誃8 稲5锳; 紻鏏誂荓8! 袲!89鸊齁鵒#*緼 ,镻璖3 +r 胓!隬鱴"醳綈 噀銟亀焫!儫崺 :飵# !釤9塳胇6舲3廚:噽缨蒏颻烻!崼踆7箵7 颎"0鮆6諊伲橴瓧獺"澃恝⿹弓塟揂'&蓹蛦#$艌鏺+搝&龍觸舘4崪軰 玤3穒雈脭=髒) 賳&橪雸揘6 +! #卻>"籗A</銄*矷蒦誠檡3璿 ;漀 + 櫐!"8鱑,0 菚岐筞峼-漬譆 +楝1y:鐘 儅痚 墱鉯餃踥&8& 遻隣踇-閛 +.<梚遲說q鲉璪/ +罶鶈'諂霜購6檊3媅嘨丄肎跘盽8閥馤薟7廟 鶄﹦1+岴璱4跾汫僕昇橰絈盡-駙卝<噕=6門&開 +譙"齝慮軼鮐6匞 鼺=('#紻硔儖鐉 瘯%桭潕"&跘)4塷誂搊 鶓 閞鯅匨!輠蹨*紷艑跲袲񙎦N5漽蟸誜3笵'籧.嘚痆砮"噓驠礑*統"彅袬蟅#龐鲍荖罝u"=盫1攉礽0錛0瘛鞺袮 鐉脟橨 +稝9骫齦 +儂= +裿驟 邟乫: 璭峼?虷s!廣覥6鮶 8 韓8檝## 旸!搥*&&婭0慹/觨#蜆3 邨 7盋誰6祪9雡!潠 +螸 " +﹖!蟨(顯8梂 6+30&$%#'廐%3玔:璟滰硚/&)鵓&=! 疪0 &=) 搷 򄐝1 !#仚$!'%0 &( *,鵍&(  > !+=% +  蟵誷籬 伆B!8*廣&獸廆橮蒣7 +镸 95%馷韈婦6貿y同飊15}85_'誮339%+罙峬4??9穂镋,38) !i跾>-9慴57鵚矰3 -/搤眳8漄;%絆璏1:8""7 򦿥 +8*,籄* +3 ;疪 $* #􅶝 +0 螾慓<:4!盞. 荙"("0:0 4 B5 *&〢 軯"4#"󸘵肞遖!0桪 ,緼 9,': %84連疍.顱06 虯/0!*颷#+6< 烳".%薉%塀 驩鏐!潱')峵)乀-2+粌9誤-嘷9𕝋(#<$ +粇 齳"嫅蒰$羠暢檉嵅僇玓 +共煐蛁;<飮誕韷2薱 +慗4碂4酽賞骵-錊儵蟜,軳疉蟍莧慭;:颼筽(﹝昄鲍悃盉蛜礬丮讄軪. 觃?%慣憡絸髣脴=齤飍摑鏘鐚檤A2嘗c#袹-!6Ae!種滸 鞡G〢 (o貶)C0稦e籑!+a +6*);8ug゛0+8鱝U5[.$"!]顳遉96 q媟8鸉Y)i #?&5; )]8-O!%*$籊""}%_烱"婸!C,覢] +60a!$O 筭%媙 +c&"7 鵏# #2*!")覰k( + O 2臥+慒m6,W緼#c!隸 +丅Y %7;鞟$紸K*+󟷣s媟w k稤璔o!41臔G +昒%m7-:M6 %#O ' +6I驠y!%; {] 8e>/ $塎7逜Y7 +*鏎Y =)a +6*O&烿昗  +!?, #e蒻2!"鮍 *鸍飈 񰳇Yc慇6). 3' {軳 _烝9("Y>噏i #疉,璛k 7**U &汮:!:e.6#u󹂡" 骮?5Q霔 +gU/&OY)=]U齳=#'鮠2+c;?M6#76誴!A%瑼7W!+WU :U/0?;"軵"9>8鮒+e 7=; 峃祍Y* m8僔W肊e!讻G 粙媟鮑 誌鶡#鵮:8;駩 +籫/璵 縿"儊筸條蟁硻亅亖龎崓塗煂縯踍b 藇塿%彙!)匛 + &莿韁驡沕 焌.馣7覲 +8遼髖+慍5鹟漎%砮=7鉕 #2("#2'6媌オ!4? 蹧贂昦 >譯U沨 < +3% +$ #3:8稯閿 弉棌;=! 亝 > 峍蚚礚3,6鱎矛 穝莍0揂+(q藚 &骹乚#<輆%#潜785誑荱塱遾褳鏻m丒- :? +4U蔀).8 +;(籌8 3񫭍6#馧籝0覫7匼 9(0銕盩 + 軶1 + 莖3 4铅颴#?%蛧銒訐鮱/ 玘閯"12$鍇蠁 ++ ) 廯/乁%粡#噲!軵 閭*C)彂O飹韃!?$檣8 7鞿 肗亀 +.8裲 $醳7譑 "i9鮪昪7齌0 縆鹡 薠)!韑' +*雥沷"媂!O錤骲9'1!砤: 稯#韋"7煔  ."罜 蓃6臛7螰 鐓檌 ; 3 珆!鹸8 8 噚7覾 !梲繎99礪&棙 檚"+賨.7稥砙7 搢!9 E5=5!遹8鞳!#7祶&笹M6稸!祡 $璪1鉞鶕?.;  肣鰾$"&# 񘰃033 "6($, 0鱌;7(/疍4 +塃"9!+![& 8" !6)鵏 *"'嘊##,3&+# ".% !++!)5(1 )&! 螦$鵍. k/鱆蚘  !6虲 +$(%*!:礏6<%逩"0  + *"70#  810,鵎  韆 -璦50!/7$筕" c鱞𫳟"0>%誘 # +m憁 +峔0&*輓 E4%: $疦裡 :1'9"蓘 髸)緽; !塉7<'7:齵 葽(:烞 7'虵#嘖.C"颵:,##5)9:!%3 *<閤鍁鵋絝貼 !?誐%."9舥稡罖 蛻= ー逧. 6 3螱 +慐 2閜!諡9A卲 沨? +肬17馝慳򿥨丳-醶?誇鶀鐠鯋%8& =髏説穔蹆3墪" 7薕* *50!$ >#.袮%虶# 9( ( 97 8#3#悱絅 峣粁噿'"9譧 廋5" +5 +18 2#!#( 6% 盡"$6 / 橭1")88#&4' 2 );$ ##(""#;1 &籋 7!; 3" " (#荄! 󎡞#"8 5 + 0 ,#$ " +6+ #"-"(4 +696 ' +:% :2 .99 7 1 誐  5#" , 6%0!_&籏1鐆橾匩o絍7 +o +隺玝1 +Y8菒 +4桪/ 媜$臕9;?]袵% +( #: 3臰!":; 儏 !镽'3"!7."蟖錞"廆 +橬<4盦) 8儧' 6,穎'( "莔婰9 +霅!=漋焁¦覶 蟚荄锧2!+"$貹<=5卼+#:$::')"+軦6>鉋烱 祍羫3鉩/ 廆08  2 + 亾 櫓 鞪#輢!璲&錎矴) $璸醗7 誐厏5\*韋"%駇G :?羬 適$?8,-旻8 > !/僶誦8655-昉 齚:瓨肑舼婫馜G񌝮63C匯7. 1僒 8舚7 長.綁議/*48閤貮稫鍕乥 +゜5馜"Q袮¦鰿窉#/>" ?1/7) 6)鏎7? +#荅+K 6e){ 峢k !僴' +籟!虸罼5籇髛藔廢I2 %(G! 蒤.婹 0 &;工-0&3-(錠:=  46(390()痑 0O/"鲌>) -!'絙( 1鱌81,"0 \5藊 +7稱- 4 1+ 橵.!鹠 󽧦隒 0汦0)$=6颵4晵𓵚"#軵 2跭, 羅醆4粇 镈/򉸮 +- 錦(38 3/9=絗)璤1 塨潁 鞼&,稰.馩'( 驟:(鸔1 #隞4譢 "'"4軬"(誥/&*汿1) ( + +匳,軶縒3 酔3鱈(價+%鉛 瓎->龍馻託+撷& +誐&%)螦虯 !1礍 %/笯>9 +%昹$縩/O廆#3<婣%/僕;3-袲廋蚚箁--2>.)髍&#跡虳(袳(/ 滻 #9 摫}2 +僜 鍃 (",1,螷*#颶卼輶1) 28 +癀7 +隤匫桲$%7#+眡}鳗*鹻":盙8峉)Ki '硁KR>k釋! _8>";c*罛򠭨厡 僲1S&婯2Y7)廈聾wc1肎S>(褘鮲m,卥C0-Q岮o𛞛 U2>^3 ]韍 "駈iS墫譍IO脋ioS笰祙U階鞟 c酇)眝薊K醗Q稧k酇-#顯Y8骬Q=a晐絰K>o盋!9 .u"錕/汸 Q沘齜!e7[汧憰W 矻1U 遹./塷(胕?僰"[+!1g洝u+穃c27_M , _&0;*,8 Q籘K ">錊S馎 岴W2峩S絃w汥筙 +!I譇9a&gk!笽(汿$酙75o 補  繆:%?烥8 7 4%<6+"〩璊# 8 鉊 !泋7鵴%莥颮憢塏 0 +  莤稨鏞c +󀶸匧!#%"= +!)󥾳' 隠儘鏗睡=玥麙譪揤蒀/ 鵶&玨 薬讍諎釛齓搘仸瓭<'烝螩4硥舊憞'2鸎笵臨岪臚醃1$彛 45廮/獵瑽%" 4蒟錓1=裲讗厇硱諑昣慚 揚嚜譣眕9粦覮询覣 嚍!穖!]鱟鬆1%#.﹥峇 +僊菒(礷盵蓞峑-閈亁憭⿴計笽絩(8)雭墮烰7儙賰僥0繈勘)%暴牛矲舿硓匧薘=乼變塒籐莻籷賊=&8 媎78鉏W# .烶 鵣 噽&監&?鉑"厔 +8!>輅+軵% +<"廍 薃$縔螮#-誇 厹6#=7+鮌 痜 7 #5 嘑=(絫*輡説 򄁭> , 礎橯!镻 &4 +%璸 + / 譍w# 塇嘨醢逨摕 *񫪔)(& ?梋">9儺 %""虰檘9漿"沷7$蒟玽叕 #0 砡 4鵴!輑誢 ?7"儎丅峾(蛒&%鞩慺4"33玌 %談臫旴璠梀'丵1玧!鵍+錬4齯鹒譙礘(烶談5媬馦踃6罵4嚁=譖軵璚絓,峇穃籕>晱誝蒕蓌罦鸍 昢 +蚢㏎>鞵<&)遃;鸏3昦烠 # +($,锳: 匑*駡;2:4.&…-?硍=玥褍-穨氡駉匼0梪( '—褃%鯄醽1.遼菬晱亭?璣僀 銟緻7'澂;蚹蚸鉼%鹴 塋玦4烸骯藣蟞(竣潐觽醫貹鮌$ 臞 矼(疩;踋'慣*籐蚈螦遠 僜𧼑/鱝 匽胻慟8镋> $罧颲 +橦9(:鰼硋76譧蚢鵐臜"錥>乺 ;郦&胈?( +亼裃貯厐 /95s4q疩"#. 籹%c笰.*k-6;g 5+W9>i 礲 絒m蟁[e罞漁# a鰿%;4e Y.廞g",+9:%[!:'絍c.$>僓獳 &g/魽I筜 u烞籓39 烿4#絘 +E1U54絰 c-鸓Y檍(鵔鏎]5#鉿棰 汵桜; o葽&岴?裯 8*稩_"< 7螶];M?U%!% 鉓W8 󂍭a!e慉#+["# +:眰6k繌.盺卆?舕酛2 踾 􅩔罷㏎藙'鏣 蒨*.)稧鏚%輇 +韎沥鵳* +J/鱒 .瓖鏼$ 鐠譤<玍%鵅跙瘡?獶荳漄鍖2颳 +賆/4 2沕!鸝&隩 裮彥醂錨>儀賫彣 鵴瘻5鬄亃1鶆S搯檙鞤晳? 蟟ヾ"峧龝3 !〥>酅潝蓋%;U#*0"仌袾= + +駆 / 貯 軿* +旲g?2?,9'輲M砆c 塉裖72讂塟' 1!'亰錼釥 e] / +箽臚  #8"-鐍 睄硙棗醐.5!廉媼转亯 O" +*K臖 !肈]%/ 37S8昩 ,>2S裫/5 薃銤跧酻 +絏o +8跡3 匱璂筈峀=$蟟縕瘹 2g/$[驪7疌- "㎝g:<鮏颯4#羆$颻;鞶漀 齺!條錦岲 +邍&4 )臝, + 05肍&:!縘艔/鐘 鏙鉔蛦 #跜隬#鱴"絸&橬1=$6虳 鉙輞)揅2梕傽 +3㎎(塤沝齉+莣 荘8觸0譗% 澶  齶 疢 荓5 +>鵛 +羘3, 峅(錏! ;)% +, 鏔F"蒞!紷+$薈韆 '蚼眡瘓,0 𹷠縁揃颳錚""軮玗""a,麗%+8旽㏄蓅!c穫/48 蛫 +"檊/3$ 瘺#)馡7覸6$*瓇 +'(8: 4厊8 隓丄"廔鱌 鞬乚"1$載-.  髃< +隠$廟2焀 󓯀昅 絧 !盄"1+讟泂祃鮋4&璪驝>荌 -諈"鞪滰踛9璍晈% 銍+鮅7亞醥(!%-遪 +1梉6镾-;#1-鞶/) .塕#棢眕4稺1 -3塗+2]*:換.P螱/3鉑荌>録仏 鮖 +酼 $縟&慴罥蒊噇覨隴笶%;峊$8'硑鏒桾)稨鉌獿,3僓㎎櫏. "縴(E硵?;蚭24媕覲婭乑鱂穒揊*踚%:$+!蛜 鼳>="跩&塮羐3??胦+誁(酑;:6〡-筎0'逥(礒(*噁亁% 1蒻3/,稤沶7塇8雑厁(5鸆&羨誑臡錥'筫?泤噅穌3踸砏錡覬桺 耄7/醘鳈 *齙檂!蚎鐠- 萤硳 弇" : 珇%齳u盨!鸻=26闅9+憌 頀揑8#疈逰!Y4輑(輔 鳜縈0"+瓆#6&峩&53橜驜 +%馌梫8 +┇硾 嘵;晎7#蒻 賯筧!#. 弰5 %籹璦&!k蒕/=炸:9誼﹉ 郓慪搙礟吵y塖脀 #涧 魼箋 +墺L梐〡 閊㎡$焮 僶7焩鶋)廳 卶;89誵繙罖 +酙=鯛= 蚔Q+馝9# %+#&僀! ?7 5獶'$鉘 +<7穉+貮0 -'-&7A7 +0-6 5?q"  (75#覩!0茾%"%/袴"璏'03# (隞=9 !觧憆#賝 踙+! +=6葽-8慇盡 +#,峛'鵪瑻3;汚 *5礚0 2?!5&:+慟 "鱀譚" 荳)𨂌?!)鸆 $閙 跩/ 隒逥8 P锳!9&/$6鞹!(%蟕  鱗( +<匭 )9 =-#." ,桵 塁%< +" *!񙘸箏眫 錷棥%<誏9< +璍&〦"旵 **5!8 )+ & "0罙揈9%:!虭#!桜% ++.3&裠5縈韝 璯 !? 輈;橞螮!733+籆m鼲. +$蒐]" 働 8Y賃 岯;:6丵/#e? ){(> S=e񋹷軥$+:(跘)8Y +𨂎鉘 >緿 A 玠a汧"M 顰k 昮󠉩_# k鸄)1跩!2廕 -鸓W>揇粸薚I7 祬*![-亾-8W#;鮈)婣[5򕶭c' +鍑 +馳"*0笯 A軮:4"7 =0廠禇賖/2>)+?&+閎) (.: 3)乢-媋 鵝8) & 〢遀 (*蒅 )?)遉,:񅜮鏬塜滿7觘璂厲1丏賮v 韓鐩髈?n 茿?顳塭9誷諟橤螦8髆薃!顰󽛫) 3.袽 )!揂婡%( 򉇼U򄡢 1K)鸇&/<貴' 玚4椋_鵯_鶒Y蛽s釃 +桸W 昛+ 梋5訂猾蟌鉭昋Q '0(瘖鹶薔 +絥5/ &鞾 +%#*'0#  焠 . 9;??籆:0+8$譆瓌臙. 酘蚥 1/'錔(嘕貹嘒!'?盓  T,揈;#鞽*贸#錕 +羨9=肂昤9鮅# 籇 3璚莗薆賁 昺$"&;!蚛 ! +砊颰稦! '#' &:6 卆"0 "=慦誆-滲4  9(,%% 慡 )韐"?1(荂'"򊁡+#嘆%廘箶(鹢i  1?7 e 9(= 塊 K8袿縄%﹚ .!譔 肒蚐莇軱閴 砶,3馧2e鱋弡g覰岴7g踄7>/6 轂醼裺7縙 𹚪0 9 aM"焔颱'箉弲 嘫 + +難 /򛿲&"17厈 :邭 ++ 羱=#蹕 鞼 費 ;Z% 酽諕7態 "+鱻"𙴎菕;乮# 47m針 粯  卽4賤5揈85酟櫂 +!蟸'<"軭7> +煇%調2鵏!髴砛酻>鵄蹣 駘# 08籸7訏, 8貺筍"瓅j#煒񆻿3(絚誏!-焳4򦽘飼諄 #񱵩4祘4c厎5 觢絢>覯' '盄閇7 +?礎環M;"I?跲 %,,8 S筯K 8 "齪O7#!A峌$[Y薲遡搎--*"7 +檋! a﹑$匒󍨃貸]7UW#> 8袹c$m)98e#9k& $[鵯]疉锳岼軨UY9 誥! +6廇i沵 +e[ 粄塠*m ";漲5/#"q罝"弌 c[=. ,5$c3S9 7焛8齩SSW( <峎/[8!S9& 9&21(0$:  !%+!I韇跩8S昲裦9S +g%鵼7G [ 汚 !(筨箎〇 6 颿!"!;>g"9 9羍ea! 輩 9_ 綉珯a7臺 #"? +龂 韏!婳5g玏丣 錋]#!筄( , c;#軮1_鸘 +M$峮 1];#S 錴+賣2e"!刊(8O泇_ !u漄?W$烡踗W昁U59/ 橜 +6k&葽 ]?莢蛨,筺)O卥 硢佗箰穄s鮴 筬i -/' <飻9q!!鏸 Q#S7盤U誣0沗 邖 (蒖a 8i<婸S賛 1a +8漒翞 箙 昐麩軫/;5%酈廕 3梒譔 6i'貴#W誈嘔7遷a# 邟 齫񗚯6M獽#Y(%!盓 k邖窉 +単 # +.晉-{礗$e5煪Mg璶W _7紺ke祝蠅"_W0錧煝7I9o8 2輂7漚"譸Q8 -K獿檼 +荳 寻!+漍S嘦 ] <籅m8匸6 +8 _, m o 4匧雃骉嘍W馟慶 +蚏縖7 +9錙M揤 GY憏 +$!G2. +3 _6媎縅W:-肊A  8" w絤匶c閊!$籌 o"S2 "k*亄傿O:;!K?譵)4Q" +M=橲"E9檏 8 ;閹'踐5 ]裧?!%k'韇 +凯1i 肰.K!檥7塏丼/傾$a  "]7-錳U鯀1橴揥k 7胣綌8 + 卋7W;!痝 + 錤c  憀!I +&舖_Q𧔧 o 蒬 qG揨7 跕6oa"鐉岶!  3:_骽 :] 昡"m鞮 U +9媉 U#""G 眹 Q#"o#彃<"瘜 a僷Y(H(6;(_鉋U8 驚2_6_3"*m晳鹔+ Q稟O+揬k茿 y鼳7$笶#<   /飏'橫 1g鐃$盢$璲0,"9  隦45 鼵6" + 廙驞闋:昿4痩飊1/羘齟彨胢7綇鯑籓壊(閨!齎<.誁 駎 酜.梫峘玈+=.憇駆%<螿臫' 0鱏(! -<昈 +誜3,)矰 賂%8#1!%1&遯% +Q蒛?揬錋*肗4焀0裮!򵦞絙>馚⿸繉礐 蒍褈*蟣駠5疭6蛺鏜仛:丩焺:範鉍龚婴鉲興飉?鏛'﹐> 4%笻泘9 +)盌'飌3譯蠠暘硜覶峕&軭矰橩潊塪鮓婮珱憇噏 廌蛈裄彮蟽璻焥洯蟿璉誱<=焠 丠骩7觰搲罚7賨鶍耄>薺弝顯痗9溪/*魼8"廼覢 汵?:7 +齬 讔輀6 $輒 !>8臰沞>89 慍𧆍>:蓂"縎#''搒9_"u%"4!8 A焜 Y(Y鶑"檻,![."&(5W摂)峼򧨳滽崿k ]賑 ' U!Q莯K匬!$閑慯 ' &#縠 鏩 +'Y1昜 +V5僊梕酠繗 酦7 !脝 鵠 貽!蚘睊 !7穕 !77隯7薳! 機9 !邒#Y齗:韾$鹹繉)馰 = :鉉 +麃 硘厊荖蒳"駗玔"( 組񟈞鼸79崍$祑7廎醏 7絭99厬7慛8#莑3絅賜 橩7桹!隺 鱜 ,遖 髕99 +;9弡昛#砨8< +慙5漨!隲 鱱:5 "舋0 慡 疛7盬 9 梍K荲7"?齋&筀 /&65鱅鵃 "覭+褦餅裯/ 鱣 雗 +%#闀!鱇+$丵 + / 酑$ +觙!;紾 +梺颋#鞞補薉$!蒰$G7覰 漥!%" 讏"" ;鮻玙並5覬 鮝; 瘞飹鵃 + 鲿7 痏匨觕 檢8籩顰9彃!!彠丟;賎"嫙7)褁螷7繐$ +廫8閍>諒86)鹺瓃"26蒔韕"+#94鏥 藧9颶,瘵$ 舚"&亃g8譿7閼唬鉤遌9塪 +蓆舑廦 鬂絀訏g峼?螥!㊣鹙(讄岵羃&駸 汭絣鵹3鉢稪〣& 3& 臟盰 +- a򣂽E$4+ 開%:!1鞶  +譧E/&馛3$7礠-8!<鰼)(5婦"〩縌.貵] 鉼 *縉乛!) +閍-&砃桟/鵆婳荾#骎 +鮥!) 媓鍇罭%>5 賒"蟜4#嘦4箎裛 貴9遦 -駃6&踄 < 瘮<酇 匑",颷紽叢鉶藖!开璒)% + /#誆𭇎+7遙礗>6 譝%荈戆璮9郗棁愍-鏐莳蒼齝鵾3籚-'遠 邰鮆*Y嘼 鸧&Y &*鵉=葾>o#鸐$W6&Y.4#軬U韌鼶Q婮6c貾"4'虴3叧1媁雊紷u矰 _絊+=4慘3k3)u疭>絉7籢籋&顳羕3gK+鞸1袸#疓E1遺-; 觰0羗c賑0u#O 礭)$稢 蠇飾3髷筦氅籺鍡5潉莶=%薸/5.﹕銦焪贍>蟌鼲/颽;9跠-m%馾-窞( 揓59箄/󸀋w#"#'汫23 +筊2﹖駆999/<21 7損)瓬;# 胏3 &? 疢鹖$ 6)焾,29丱= 1 9荹鸑鮎墂+7棸暔闃麞=5臚. +?鉣2礦 +.鉖" 砄+$ +>#鸮0"? (絆頌誳6 )3.-4  +岪鞦?馟&袰#%譐77*雊嘓(疈婸 &>慗籒""𲤓% 疞9 +鞰軱蚞)隨 #  $沢5 9: =&:8顱 &, 肍$誯慞$+ (* &烪Q匸 c 0覵1貱) 玨 +9{議 +E馯 +5Y9 _,!9g縨酓(8+$*蒃a" +祕蓳秊禋!'c昛#7厛1#隡礵嘠 繍卭 +閏"箊8貿 5閐鉊!籄)馜"-"臞 9 譆$$ +8%"(軵 :򊰔 <盄$99#/ 譊+)#蒓' 颪< 鸄%"(譒"4?3譴 +$6C籊*7'紺 : )滼髄 7鮂 +跴>* 6盶A1 +4?4! ?誆񾆄 (? 媟 )9#&!疪8%#(8稝 飶 +镺4>搑筁6梣$塅梤"塃. 鏷"遪慪 : 烰!裀 +0#) 鞸誈隚#/69+踠莕 7>鸏*"縘 +/踤廻 -蒄+!罻 鶉隓-錠驣+"縟 6廈蓛 +9 瓔I噿煋瓡 ; +6򄬊蚒"#馼酖)懏暎濂愆<鸓讒 +"荌*3穲羒儤賔嘢櫌?駌6 '驲祏肸颣逧: 蟝,檞罚7齂-蟋*飈' %盨&製%婨覩馭 飤遃,貸㎏憈羪洕02礑9c鉝桺1 跘9舎' 5珬 335 %  *漗1蹨﹎厵1s&37薊 ?匓 '. 3莬 -髲U#!镹罷 5!覼齷 "?鱋胹6Q輂7肶 e醊蒁9-姜9踾91’誂""綀肞<諅!6)壉-鱷5祲!w#雟昞筫虴痻韰縌 !򵍣稴> <> #璂嘗貽 ;6:煍) 絖 稲;媖 <誃8荓盦>鏏5锳; 紻礏¦誂3袴 *緼 袲8!!89*:3鸊齁鵒# 縋璖3 ,镻 +r=:/$" & 6'㏑e#醟 鯁紻 蚭 卹&鐉焫 8飵逽贉嚇<鮡%礡 9 )"4 ?&跘4卥鮤) $4嘨5*肻8"誫韼9>-滱 飬邐 髒雈&脭=) <閞&!醦 + #鱙 7揘6 + a 跲&!*荓4蠙 8A 2 +/<&罻 醄 0 痷蚙隣.鞢7=1岈2 ++'醫 蒧#y3󞪥.: 痆鵌-*!雽驠( +蓱岲"6*譆8袬(-玤3,6/#.璏,u"僑=荖)讂鮆*"齝%&0 睎+'息錛**馴.瘛<袮  遲Y/1說 嵁'橨  +, 篃9)/ +4諘󠃚骫 韀0鹲'絤 += +羈驟 袬裿笲6/邟:#颺7 璭峼;6?s!檝鮶須 8 韓8!顯(蒥 #'誆$# 旸*&&!搥$$"5婭0僗慹(譌#3 ;>.6 󎂴9覭;鱤!3 +螸 " +誂2=%+梂 6'廐%30& 󫬅$%#3玔:璟滰硚/))鵓&-;! 疪&= 1紻 򄐝=)0 &3( 搷>'1 !# *,鵍仚$!'%0 &(& > !( +B!8 +< +4 卼 蟵籬 ?*廣廆&獸詹鵨5 %邁 \ No newline at end of file diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.nrm b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.nrm new file mode 100644 index 0000000..dc21226 --- /dev/null +++ b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.nrm @@ -0,0 +1 @@ +NRM|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||vvwv|vwvwvvw||v|wvwv|y||||wvvvwvwy||v|wwvww|vww|v|w|||wvwvyw|vw|vv|v|y|y|||vvvvvvwvvw||w||v|vvv|vwv||wwwvvwvvv|v|wwwvy|w||vwwvvvvv|wv||vwvyvvv|w|wvwwwvvwvvvvvw||||||vw||w|w|vy|vw|vwvwvvv|||v||wvw|v|vwvvvvvw||vv|w|v|vww||||wvvyww|||||vwww|y||w|wxwv||v|wvw|v|w||ww|w|ww|||vxvw||v|vvv|y|vvwyvvv|wvv|y|vvyv|wvwwwvv|wwv|vw||vvw|||vv|wvv|vywvw|v|v|ww|wvvwv||vvwvvvvy||wwwwwwv|w|w|v|wvwyvvw|||wvw|vvvwvv|wvwv|vwv||vv||yvw||wvvwwv|vvw|wv||ww|vvww|wvv|y|v|v|ww|vv|vwwwvwv||w|wwww|wwyvvwww|w|vvwwvwv|v|vvw|||w|v|wv||vvvv|v|v|wv|vv|ww|w||v||w|w|vv|wwvvwvwwvvvwwvv|vv|vv||w|w||v||wvwvwwvwv|wwv||w||wvvwwvwwwwv|w||vv|v||wwv|ww|||wvvww||w||wvwwvvvvvvv|||wyww|vvywvwvwvw||||vwvwvw||w||ww|wwwvww|vvv|wvvvww||wvvwv|v|w|w||w|vv|||v|vvw|v|v|vw|vvv|vwvwvv||w||vvv|vvy|v||||ww|vvwv|vv|vwvw|w||vvwwvv||wvv|v||v|yvvvv|wvwvwwwvv|vvvvvwwvv|wvwvvw||vwv|ww||w||yvyv||vwvvwwwyw|v|wvv|vvwv|v|vwv|wwvyvv|vv|wwvwvw||vvwv|wvvv|vv|w|vywyv|vywvw|wv||wv|wwvvwwy|vwvv|v||||v||w||vvw|v|v|w|wvyw|vwvv|wvwvwvvwvvv|vw|||w|vvv|||v|wvwwwvw|vvvv|v|vvvvywwvww|||vw|vyvw|vv|v|||vv|w|vvwvyvv|vvwww|vv|vvv|vww|vvwvvwvvwywvv|vwwwv|vv|wv|v||vwv|vw|wvvv||wwwvwv|||vww|vvww|vw|vwvwwww|wvyv|v|wv|||v|wwywwv|||wvwvv||||wvvwwvv|vwvwvwv||vvwwvwwwvyv||||vw|ww|wyvwvvwvvvvvvv|wwvwvwvwwvww|v|wv||v|v|vvvvwvwv|||wwyvvvwvvvvwv|w|wvyv|wvw|||w|w|w|vvwv|vwwwvwwvwvw|vww|vwvvw|vvv|vvvvwwv|ww|w|vww|||wvvv|vvw|v|v||vvwvwvvvvv|vwvvvvvwvyw|wwvy||wv|w|w|v|vwvwvvvwvwvv|wwwy|y|vw|vv|w||wwv|v|vv|vwyw|wvy|wv|||wwvvyvw|y|wv|w|w|wvvvywvw||vvvv|vwv|vw|wv|ww|||v|wvwvwwvw|vwwww|w|w|vwwvw|w|vw|vww||vwv|||vwwwvv|wvvvvv||v|vwvywv|v|vvvwvvwvv||v|vvw|ywv|www|vvyw|vv|v|vww||w|wvwv||wvvv|w|wwv|vwww|wwvvvvwv|v|v|ywvvw|vv|vv|vw|vwwvwv|vwww|v|yv|v|y|vvv|vvwvv|vw|vwwvwv||wvwwyw|vvvy|vv||ww|w|wvwww||ywvyy||wwyvvww||vv|vww||vvvwvvvwwww|ywwvvwwwwvvwvv||||vvvwvwv|yvv|v|v|vww|w||vvvv|vvwvvvvw|wvvv||ww|w|w|wv|vvvvywwvv|vv||vv||vwvvvwv|v|wv|vwv||vvwv|vvyv|vw||wvw|wvw||||||wwwvvvvvvwvv|vv||wvwvwwy||wywww|vvw|vvvvvvww|vwvvvwv|ww|vwwvv|ywwvv|w|www||ww|vwwwv|wvvvvv||vywv|v|wvvvwvvv|vwvwv|ww|w|wvwvwvvwvwwvw|v||w|v|v|vwv|wvvwwwvv|||vwvvvwwwvy|v||w|w|vv|wyww|vwvvv||||vv|vw|vw|w|vw|v|vvw|ww|vw|vvv|vw||w||w|wv|wv|vvvvvwvw|ww||vwvvw||vvy|vvwwyvv|vvvwwv|vwwvwvwv|vvv|vvv||vvvw|vww|vv||vvwvvvwvv||vvwvw|wwv|vw|ww|wv|wwvvvwv|||wvvw|v|yv|vvyvw|wv|wwwwyyv||vwvyvyvy||vvvvvwvv|vwv|vw|wvww|vv|wvv||wvv|wvvww|v|wwvv|wvvww||v|||||w||w|wwv|wvww|wvv|vv|w|vvwwvv|vv|vwwww|vvvw|y|||y|vw|w|vw|vv|v||vw|y|wvw|v|||vwvyvwww|vvv|wvw||v|wwv|vv|||vvv|vwvv||v|v|v|v|vwvw|vwwvvwv||vw|||vv|vwwvvvwyv|vvvwyvvwv|v||vwvv|wwvv|wwwwvwv||wvvvv|||vwwvw|||wvvv||w|vwv|vvv|v|vwvwvwwywvw|wvwv|||wvw|vvwwww|vvvw|v|wwwvw|v|vv|wvvwvvwvvvvvyvw|wvxv|w||w|vvwvvww|vv|vwvww|v|y|y|||ww|||vwwywwv|||yvww|vvv|w||vv||v|vwwwv|w|vvv|||w||w|w||vwvvwyw||vv|v||w||||ww|||||v|vwwwvww|v|v||vww||v|vvvvw|w|vvv|wv|vww|||w|wvv|vww|wv||vvvv|wvvw|||||v||vwww||vw|v||xv|ywv||vwww|ww|w|wvv||wvvvvvwvw|wwv|wwwvw|w||vwvwvv|wv|v|wwv||w|||wwwvwvwvyww||vwv|||yw|vv|vwvvyvv|v||vwwvv|vwwv|vyvvvw||yvw|wvwvy|vvvvww|wywwvwvvv|vwvvwvwvw|wvwv|wwwvwwvv|||vwwvw|w|w|||vvv|wvwv|vwvvyvv|ww|vwwvywwvwv|w|vvwvww|wv|v|wvvvvv|w|vvvvwvw|w|vyw|||v|wvwywvv|wvvvvwvw|w|vvwwvyw|w|wv||w|vvwww||||vww|vvvww|w|vwvvwvv|vvwvwvvwwv||wvvxw|wvvw|vwvwv|vww|y|v||vv|wvwv|vw|wvw|wvw|vwvy|vwwv|w|w|w|vv|vvvvwvv|wwv||v|w||ww|wvw|v|wv|vv|v|v|||wv|vv|vv|vw|vw|||w|ww|w|v|vvwwvww|||vv|v||vvw||wwww|v|v|wvwvwv|||w|v|v|ww|w|wvv|wvvvvvwvw|vwvww|||w|vww||wwwvwv|vwvwv||w||vw|vvwv||vw|v|v|vwvyv|w|wv|vwwv|v||wv|vyv||v|||wv|vwvw|vvv|vw|w|||w|yww||||wv||y||v|vvwv|wv|vv||||wv|vv|wwwww|||vvwvw|wvv|vwvwwwy||wwwvwvv|w||||vv|||wwwyww|vw|w|ww|vvvv|w|vw|wvwvwvw||v||vwvvww|wv|||vvwv|vv||vvvvxvww||wvvv|vwvw|wvvv||||v|ywvvwww|www|w|v||wv||wv||w|vvvvvwvvvwvv|wvvvvv|w|wvvvwwwvv|wv|wvv|v|v|vwwv|||wv|y|ywvw|v||vvv|w|vw|wv|wv|wwvvwvvw|wvw||v|||vw||wwvwv|y|w|vwv|w|v|vvwvvvww|ywvv|vw||vww|vvwv|wvvwvw|vvwv||vwwv|v|vvww|ww||||vyvvwvvvy|v|vw|v|v||||wwvvwwwv|wwwwvvv|wvywvwwwwvv|v|www|v||v|vv||||vv|wvy|wv|vw|||wwwwwv|v|yvw|ww|wvwvwvw|vvvvvvwwwwwvv|wwwvwwvwvvwvv|vwvvwyv|wwyvvwv|||w|wv|w|ww||vvyw|w|w||w|wvvw|wwwwwv||wyw|y|vvww|wyy|||vwwwvyw||ywww|wvvvwvw||wwwyw|vwwww||vwwvvvwww|wwww|wwwv|v|wwyv|vwvv|vwvyv||wvy||vvwv|wwwv||wvvvwv|v|wvw|w|ww|vvv|wvww||wwvy|v|vw|vv|wvv|vvv||wwwwvvv|w|wwwww||w|vvv|wvvw|vv||w|y|wv|||wvv|vw|vvvvv||yw|w|vvwyvyw|vvyv|wv|||||wv|w|vvwvv|w|v|||vvv|w||vv|vwyw|v|wvvwwvww|vvyvv|w|vvwwwwwwwwww|vv|vwv|vwvwv|ww|||vw|wwvvvw|yw|wv|wvvvwvwwvvww|v||wvvywvwvvvww|w||vv|vv|vwvwvvwwv|v|||wwvvvvw||vyvww|v||v|vw|wv|vvvvwv||yvwv|yvwvwv|||v|ww|vvw|w|vvwvwwv|vw|wv|||vwv|vvwvvvwv|vvvvwvvw|vvv|wvvyvv|wvvv|||wwwwvwwwv|wvv|wwvwwvvvyvvww|ww|v||vv|vwwv||vvwvvv|wvv||w|||wwvvv|w|vvv|vv|wvv||||wvwyv|v|vwwwyvy|wv|vy|v|vvwvvvw|wvvvwvw|yww|ww|vvw|wv|v|wwwwvwwv||wvwvwwww|vwwv|||yvv|vyv||vvvw|v|ywvvwv|v|v|v||||v|w|vww|wwwvyw|www||vvvvvwvwvwvvwvvvwvvwvvww|www|vv|vvv||||vww|v|wvvv|wv|vwv|vv||vv|wwvv|vww|vwwv|vvv||wv|v|vvwvwvww|v|wvwvv|vvwv|yvw||wwwv|w|w||vv||y||w|vw|||vwwwwvv|v||vy|vwwy|wv||vw|wwvyv|||vywy|vvvvvww|wvw|v|v||||vvvwwv|||wvw|||yvv|vyw|wwy||wwv||v|wwv|w|vv|ywwvwwy||yvwvwvwvvvvvwvvvvywv|vw|vvw|vwv||vwv|w||v|vv|vvvwywvvwwwv|wwww|vv||vvwvv|wvw||v|w|v||v|||||vwvvwvywvvvwv||vvw|vwvvwww|wwvwvwvvv|vvvww||w|wvww|vvv|wvwwvv|wywvv|ww|vv|vvv||yww|yvv||v||v|vvvv|vw|||w|vv|wwwv|vvwvw|wwwwwvvwyvwww|||vvv|vywww|vvwwvwwvvvvw|||vwyv|vv|vywv|w|vvww||wwvwwv|||vwwyw|v|v|v|wwv|v|wv|ww|vyw|w|w|wyv|vwv||wv|wy|vw||vvv|wvvw||vw|vvvwvywvvvwvvywvvvv|vvvvwww|yv|v|www|vw||v|||v|vywvvwwwwvwywvv|vwy|vwyw||vvw|wwwwv|w|wv|w|v|vv|wv|vv|www|vwvw|||vyv|ww|wvw||wvw|wvvy|vww|v||vv||||wwv|vwwy|yvvwww|wwvw|vwwvvvvvwyvvvwvwvy|wwvww|v|ww|www|v|w|v|vwvvv|vwv||v||wv||w|wyvvvvw||wvvwwww|yv|||wwvv|||y|wwvv|vvwvw|v|vvwv||vwvvvvvvv||vvvvvw|yywvvwv|yv|w|ww|vvv|vww|vvvv|wwv|y|wwvwv|wwwwyww||vwww|wwwww|vvw|vvvvwxwwww|w|vvy|v||v|||wvy|vvw|wwvwwv|vvwwvwwww||vvvw|w|w|vvwwwyvv||vwvw|ww|vwywv|wwvvv|wv|ww|ww|wvy|w|vyvwwvvvwvv|vv||v|vvwv|w|v||vvw||vvvv|vvv|vvwvvww|wyv||||wyvvww|vv|||ww|wvww||v|vvvvv|vwwvvvywvv|vvvv|wwv|vv|wvyw|wv|w|v||vwvvvwvw|vww|www|v|ywv|w|vw||wwwvvvvvvw||ww|vvwvv|vvvywvwvv|vwwwvyvwvvvv|wwvvvv|wwvwwwwwwwv|w||v|wvvvvw||||||wv|w|wvwwvvwwvv||w|vwwvv||v||vvv|vvvvwvwvwww|vvw|wv|w|vw||vwv|v||||w||wv|vvvvw|w|v|y|vvwww||wyww|wvvwvwwyvv||w|v||wvvv|v|w|vw|vvwwvv|w|v|v|vv||vwwwww||wwvvww|vvv|w|vwvvwvvv|v||vwvvwwvwvvww|wwv|vvvvwwvw|ww|wwwvvvvvvv|v||v|vv|v|vwvvvvywyv|vwwvwvv|vw|vww|vv|vvv|||ww|www|vwv|y|v|vwwvvvvwvww||vvvwvv|wvv|wvv|vy|vvw|wvw|v|wvwvwwywvvvwv|wwwvw|wvw|wv|v|vyvww||vv|vw||w|yv||vv|wvyyvv|wwv|vy|vw|vwvvvvwvvwwvvvwvww|vww||wwv|vwvvwwvv|wwy||vwwww|yvvvyvwwvww|||vv||vwvwwy|vvvv||vv|vvwvv||vvvvy|vv||vwvw|wwwvw|w|v|v|wwwvvv|wvwv|w|vv|vw|||vvwwvvwvv|wvwvvww|vw||wvvwvvyyvvvv|yv||v|vvwv|wv|vwwvvwwwvv|wwvvv|vv|v|vyvvvwywwvvvvvwwvvv|w|||vvv|vww|vvvyvw|w|vvvvvwvvw|wvwwwwvvwvvwvw|vvvw||yv|vwv||wvwwwwv|vwwvw|vywwwvv|wwv|vv||vwv|v|w|wwwyvw|wv|w|vvwvvw|vv|wwwvvw|vwwvv||v|v|vvwvwvvvvv|wvv|ywv||v|vwwwwyvv|vv||wv||||w||v|||vvv|w||yvv|||w|v|vv|y||vvvy|v|||vyw|v||yvvw|v|||www|wvvwwvvv|vwvw|w||w|v|w|v|w|vvwv|v|vvvwv|vwvvw|wv|wv|w|v||vw||w|v|wv|vw|||wvy|vww|v|vvww|w||||vvwv|wwvvwv|wyv|yv|y|wywvyvvwwyvwww||w|w|v|wwvy||ww|w|vvvvw|w|||vwwvvvvvwvv|www|||vww|||v|wvwwwwwv|ww||wvvwwv|wwvvwv|v|vv|vv|w|||vv||v||w|wwv|vvw|vv|v|vv|vwvv|wyww|v|vw|vvvvwvw||vw|vv|vv|vywvvv|ww|vw|wvywvwvwww|wwvwvvwv|vwvwvwwv|vvvw|vvwv|v||wyw|ww|yw||wvvwwv||v|v|||vv|vv|ywv|vvvvwvvww|wvv||v|v|v|wvwvvwvw|vwwwv||v|vvvv|vvw|||v|wvvvw|wvww|v|w|ww|vxvwv|wyvwwvvvw|wwyvv||wvvvvwwvw|wvw|v|v||vv||wvvvvvwv|wvvv|vww|||vv|vvw|vvvww|vvwvv|||yv|wywvwvwvwvwwvwwv||vwwwvw|||v|ww|yv|vwwwwvvw|vvy|wwwvvw||w|vy|ww||ww|vw|wwwyvv|vvwwv||vww|vvwyvwwvvw|wvwwwvwvw|wwwyv|vvvw|wwvwvw|vvvww|w|||v|||vwvwy||w||vwyww|vv|w|v|vwwyvw|vvvvwwyv||w|vvv|w|wvvwwvv|v|v|vvvvwwv|v||vvvvy|wv|||ww||wwvvwvw|yvvvvyw|ww|v|||wvwvvv||wvwvwvw||v|yvwwvwvy|wwvw|v|wvwwvww|v|yw|wv|vv|||w||wv|ww||vvvvvvwvw|w||v||v|w|wvvwv|vvv|||v|wwvvvw|www|v||vvvwwwvvw|vv|yvvwvw|wwwvwwvwwwvvv||vv|vw|||vwvwwvvwwvwvwy||vw|wvyv|wvy|v|wwwvvvvwyvww|||vw|wvv|v||w|vvwwvv|wv||v||vwv|w|w||vvwvw|wvvvv|vwwvwv|vv||wvvvwvwvwvvw||wvwvwyvww|||wv|wwvwwvw|v|vwvwv|wv|wv|w||v|wv||v|v|vv|vv|ywvv|vvvww|v|wvvvvvvvw|v|||vv|ww||vww|vw|vvwvwvvvvww|w|wvvvvvw|wwwv|yw|vw|||v|wwv|vvww||vwvwwvw||vvvv||||||vww|wvvvw|y|vwvvvvv|vvw||vwwvv||wvw|wwv|w|wywvw|v|||vvvwvvwvww|vwvwww|wwvwvv|wvwvw|v||wvwwwvvvvvvvvyv|wvywvwvvwvvvvv|v|w|wwww|wwwvvwwwvv|w|||wvvw|vvv|v|vv|yvvvwyvvvwvvwwv|wvv|vvvvywvv|||vyvwvv|vvw|vv|w||vvvw||v|vvy|ww|v||vww|vv|||ywvvv|w|vv|v|wvvvv||wvvvvwvw|wwvvwv||wvwvwwyv|vvw|w||wvvy|vyvvvvww|||wvvv|vvvw|vv|wvww||yvvvvw|wvvw|wyvv|w|wwwwvwvwvwwv|vv|vwvvwvvwwvy||vvwvw|vvw|vwyvwvvv|w|y|vw|vy|wwvyvywwv|vww|v|w|wv|wv|w|vv|wyvvv|vwwv|v|yvvvv|vwvw|v|vv|||w|vv|wvwvv|wwvv||||vvwy|v|vwvv|w|vvvwvw||vvw||w|wvvww||wv|vw|wwwwvvxwwvwv|y|vw|vvvwwv|y|wwvyvw|vwvwwvw|y||wy|ww|wvwvv||v|vv|wwvvwyvwvv||vvvwv|vvvvvw||ww|wvvy||||v|||vv|vv|wvvvvvw|wvwvwvww|w|vw|vvvv|v|vvw|v||||||v|vv|w|vv|ywvw||vvyvwv|vywyw|wvvw||wwww|wvw|wvvwv|ww|vv|vv||vw|ww|vw|vw|vvw|vvvv|w|wvwy|vwvvvvwvwvwwvvwv||v|vvvv|vvwwvwww|wv||wvv||vwvvvwvvwwvvwvv||v|vvvwvyvw|wvvvyvvvv|vwv|wv|vvwvv|wwv|v|yvwwvvwvvwv|||w|y||||w|ww|vv|vvvwvvvwv|wv|vv|v|v||wv|w|vvwvv|wvvw|||ww|vvwww|vvv|vwv|wywv|w|wwy|vvw|vvww|wvwvvvw|w|wwywvvvvvvwvw|v|vwvvwyw|wv|v|w|wvw|v|vwvvvvwyvw||wwv|||w|wwvwv|vywvvvv|v|vvww|ww|w|v|vww|wv|wvwvv|wv|vv|||vw|v|ww|v||w|vwv|vv|w||vvywwvv|wv|yv|y||vvv||v|wyv|vyvywwyv|v|wvvywv||vwv|||v|vvvvv||vww|vvvvvv|wv||w|v||||www|vv|v|wwwvwwywv|wwwww|||wwvvw|wwvvyww||wwvwww|vv||wv|||vvv|wv|||w|vwv|yw|v||wv|wwvvvwvyvvvvywvvvwvv|v|yv|v|vyvwv|w|v|v||vvwv|w|wwvvwwwvv|y|wv|vwwvww|v|vv|vv|www||vwvv|v||v|vvw|||v|||||wv|wvv|v||w||vvw|wvw|vvvywvvwy|wvwwvv|vwv|y|vv|vwvvwvyywvv|v||vy|v|wwvvvy||vvvwvwvwv|v|vvwvv|vvv|vwvvvvvvvwwwwwvw|vvvvvww|||||vv|vvwwwvwvvv|wv|v|vwv|vv|v||wv|vvww|||vww|vvwv|v|wvvvw|vwvv|w|yv||vwvvw|vvvvvww|w|v|wwvvwv|vv|vw|wv|yv||wvw|vvvv|v|wv|wyywvwwvvwvvwy||v|||wwwwwwvv|wvww|||wv||v|v|v||w||v|w|v|wvww|w|vvwwvvvvwwvw|vwv||wwwww|v|||wvwvvv|||vvw|v|vv|wvvvwwvvvvvv|vwvyvw|wvvy|w||wwwv|yv|v|vvyvvwvv|vwvwy|wv|y||w|w|v|||x|wwvw|wvvvwvvyvvvwwv|wwvwwvv|w|wvwvvwwwwvvv|wv|vww|vwv|wwvw||w||vv|wvv|w|vvwwvwwvvw|wwwv|v||vvw|wwwvvv|vv|vwv|vwwwv|ww|wvvwvw|v|ww|||y||v|wywvw|vv|www|vwwwvvvvv|vwv|w||vvwvwwwvww|vv||vv|vwyww||vvw||vvwvwvww||wvvvv||wvw||wvw|vvwvvvvwv|||v|ww|wvw|vvy||www|w||vw|w||wvw|www|wwvwww||vvw|wwww|wwwvwv|v|vv|vywvvwy|vvvwvwvv||wvw|v|w|vv||wwwv|vw|vvyw|vv||v|vwvvvv|||wwvwv||wvwv|w|vwvw|||vv|v|vv||vwv|w|v|w|w|v||v|vw|wvwwv||ww|wvvvv|vv|v|vw|v|v||||yvvw||w||vwvvwv||w|wwvvvwwv|vwy||w|v|vwwwvvv|wv|vvww|vyvwy|vv||w|v||||w|ww|vv|v|wwvvv|wvwvv|wvvwwvywwvvvv|wwvw|v||vvyv|||vw|ww|wwwwv||vvwwvv|||wwvw|v|v||w||vv|w|vvyv|||yvvvw||v|w|wvvv||wxwvwwv||vww|vww|v|vwvv||v||wvw|w||vvwwvvvwvvvvvv|vv|w|wv|w||wvwyv|vvwwv|vv|v||wvvwwvvvww|vv|vv|||wv||v|wvv|w|vw|wwvwwvwwwvwv||wvvwvv|vw|vwvv|ww|v||vvx||v|wvv||wwywvwww|w|vw|v|vw||w|v|wv||ww|vvwvv|vww||w|vvww||vvvvv|vww||vvvvvvvw|wy|wv|wwvww||||v||w||v|vwwvyw|v||||vwvw|w|vwv||y|vwvvvv||v|wwvv|v|yvv|w|wyw|vv|vv|||v|||vwv|vv|wvvvww|vw|wwvwvwv|||wvwv|vvvwvw|vwwwwwvv|vvv|ww|v|vwy|vvwvv|||v|yvww||vvx||v|ww||vvwv||wv||vw|w|wv|vww|ww|vvv|v|w|vvvvvvwvyvvvy|ww||v|wvv|v|vwvw|vv||vvwvv||wv||vwvy|v|vwwv|w|||wvwwwwwvw|wv|v|vvwwvv||vw||wv|wvvyvvwvwv||yvv|w|vv||vwvvwv||wvvv|v||vv|v|||ywyw||vv|w|||w||v|v|vvvy|wvvv||w|www|vv||www|w|w|ww|vvww||vwvv|vv||wwvvwwwvv|wwv||||vwv||w|wwwvvw||v|v|w|wv|vw||vy||vvwyvw|yvvvv|vvvvvw|vvvy|vvwvv|vvw||w|wv|www|ywvvwvvw||ww|vvv|wvvv||vvvvvy|wv|ww|vv|wv|wyv|vwwv|wvwvvwvyww|w|wvv||www|w|w||v|www|||vv|vwv|yw||ww||wwvv|vv||wwwvvwvvwvvv|ww||vw||vvwwwvwwvw|vvww|v|vv|vyvw|wvyv|w|vv|v|v|vv|w|y|v|vw|vvwvvw|vvvvyvvvwvvw|w|vwywwy|vw|vw|vvvwww|wwww|v|ww|ww|vvvw||wyvwvwvvvwv|wv||yw||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| \ No newline at end of file diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.prx b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.prx new file mode 100644 index 0000000000000000000000000000000000000000..d258335c2f5676d43b624c9aa826db0dd56ea95f GIT binary patch literal 129208 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 Y1CN2nz+>Ps@ECXuJO&;E|GzQtKceJ@Pyhe` literal 0 HcmV?d00001 diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.tii b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.tii new file mode 100644 index 0000000000000000000000000000000000000000..ddc96f2036244ca3327c06bf4e42ec2808a0a4f1 GIT binary patch literal 21142 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 E2Sq3T8UO$Q literal 0 HcmV?d00001 diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.tis b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/_8.tis new file mode 100644 index 0000000000000000000000000000000000000000..dbedb6207f47ed6e02ef963853ef73d2d6d21d54 GIT binary patch literal 1324039 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≪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

  • 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 Drq)p} literal 0 HcmV?d00001 diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/segments.gen b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/segments.gen new file mode 100644 index 0000000000000000000000000000000000000000..774fd07ae746de23e5e6dc5639f7731e5b65f279 GIT binary patch literal 20 QcmezW|NlP*2;hX#07?@C4gdfE literal 0 HcmV?d00001 diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/segments_9 b/.recommenders/index/http___download_eclipse_org_recommenders_models_oxygen_/segments_9 new file mode 100644 index 0000000000000000000000000000000000000000..b348853b4922f2536ee2de7eaf5151b96b51b2c5 GIT binary patch literal 244 zcmYjLIS#@w5OhG{hJqKkhpcSlpg>EDL`99PV3eR>Bby*f-ogv`85MO{A__*k+GA#q zs;b_E1lz}R8xumh=s|M^abuSdGJREl2 + +192.168.30.128 +5555 +F://monitor + \ No newline at end of file diff --git a/Server.bat b/Server.bat new file mode 100644 index 0000000..7b9c53f --- /dev/null +++ b/Server.bat @@ -0,0 +1 @@ +java -jar Server.jar \ No newline at end of file diff --git a/Server.jar b/Server.jar new file mode 100644 index 0000000000000000000000000000000000000000..340b2b114450f88c78e38bc23c32e3f4cf6a9a36 GIT binary patch literal 152588 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 + +192.168.30.128 +5555 +F://monitor + \ No newline at end of file diff --git a/judt/bin/Test/TestClient.class b/judt/bin/Test/TestClient.class index a7528d0cc8a52328bcbdd507408d0bb15ea5df54..f0d20459bfe252bcf29d5709c47aff4b250b4b68 100644 GIT binary patch delta 758 zcmZWnOHUI~7(I7p+G&RoOCMq>wiQKNw3e5z7Nu6JSP`lqwV>!=C$&0#q@8M5b>+e( znY~+9h6Ix#O2Q9t@6v?}W8!a6@td*&ax>rL-kfv3^PPJ?IKNBM*MDDj0E}a0P5Q=- z4X^zeX^ZG%=zXQUQR13XEyd^bM!8x_x5`>kZ8*@+(DhQ)v|9LWtx*h1@FOV0h7f}< zGJTMij4oJ+lQITyioveb>uR;g&>zW04}m*9UaO6yMH!TF24@)@dTq}EgEw-RL)a+J zi5OyV9c(V+JYu9!QuXwzt~MEjNOUPJ!G*YtVT>5dthYTT)BJV@+Y7DMRGqklDYDLCXBpCQwOQ%`)+?Q+d9L1xPMOCRJ9hjgYe|>!abLX9e>qv>1Wbky1?T5;^ zVMQj^yDhp_b>b#6B5oOd+yH+YcZ^AHe9$J*={*_KxKI9?nyS{V8M0QWvv?pP#}G6E ze2|y%(D=-aIrwU;!oae|Z*E1H7qMvM_*VNb1lZ}G7o4eWxC&cv&&1rG9^WSuzWg@) z1$STzCqgE|CQh4(B!rk>FmWLtGcme}i|(X}Ynw=WF=ZmV4k=;t+f2-aBqg=Jy8%WC zW-vvbcu3S|6f#u_9F9=!Zo`YCbWJYGyoaD3OwdUNK4fu>NXIdUE?U+@v{^Q3KTm&- z>Lc1Q61j^!9+P|&LnvU82Fen42~Vg#C2RovA8^7h$qFKt>2ryA1}0+GE|J3Xj-K)# DfnlJN delta 518 zcmZ9I%}*0i6vcmUrZVkw)Y?*lqF9R`EiD#osUI~U2ntvb#n7l5Co)0I*b-VbCMK?2 zxFoYT?pV3OWK1+6alwW}cP>qEVf-(s*Dl?>irih-Ka5gw z{nyZ7n4=2)*!8@6@jaGH){U;4p#W?B>FjLlg(M0w=Z8*aq^suKETqv<}i$uZ!M8Ods1(edZQ+uvJn zG(!|D&MV?=+)6z^FRZ2zT}L*G3@fbFf09>IB+`}tQDak|!A(k?TnQN2XnmU-2pHdJZKFt0 zpd>UCE%*A{uT7W(#5hPdhv=2UQZn@u7jLITPTZ#~#{KPub_{MXB~w@o)6B@(ZfXA} j6%4V5m}O1?x5UvUN{eAki+PKv#ch-&c*Pz0HCXry7I$a^ diff --git a/judt/bin/Test/TestServer.class b/judt/bin/Test/TestServer.class index c616c31208fae644d316c5dfef16c33f74f589d0..ee2d60908ecb23c9c3b4802ac5a04c4bd16eb9d3 100644 GIT binary patch delta 183 zcmcb}agu}U)W2Q(7#J8#7`!KP9p~pWv^3H)G_%k%HqbLPvY2?^fU$V80OKJYE(SdY z19k>|Mh5<@(v$*y5D}c8oSj<2!(hl@#K^#!o?7DR!pOj^p*i_KV;Qp~1KZ{XCR;|v zZIkygdwAP3H~?+o1*&yqaAII&5NA+faAt5}U}8{b5Mgj-aARO*a0ja3U|{^iAjHlf X0F?0n@|hSs8N7fr7f_EPkOl$(y+9%< delta 164 zcmX@fagl@T)W2Q(7#J8#73IG5A delta 58 zcmaDM|5|ZZ;1N0i diff --git a/judt/bin/judp/judpClient.class b/judt/bin/judp/judpClient.class index 80e3954d75aae7e81820091ff0e6f2d5da0264e1..935a5ef65ebfaf97aae11900b709962e24b30b5b 100644 GIT binary patch literal 4703 zcmb7HZBSfi6@KpS!Y<1V5WWHg@|_4v2!xWvh6I}>UrUxHb_s2WvArxeWRqnVckia5 zZ5sP!O|7jT)izXZV{6fhHfh5qHJ$u%tTXk8U!(sV$C>Ilj-$@_%h48}^WM7)iNtCM zd*6NE^PY2_bDnd~<=qc{a2-Gw-txkwq5MR4bfR58dJ}OoX?fw%P;tUIWwa-Z4W@YjG0z%YJ4P~6m_G9Whmj|9r0w`>d{c!9G>?mYNg}J zvF=dI5LNZ2MomB5sMb+|8V&B|mZ1`8Sf-;0#j>i`;e}6D%XO4O_o7Kd)gq?-XhgNh ztors>FOsI!9^%KY(b2S-$>{h9nl+RVLvS);j57{_Mf`2C zA>4Gi+m8S?deN$(si6E&@?N|GbgNgDygGQ@Rd&xycM+=w869yGreeM z$ZyDqADggQ!qKUr!Exkfs|=o>6rkZP8tMv$qp8?QbKa&TJDxNn+3^uGJ!p(12(2=l ziW!L^BORCT&ZfsY9?xi4YG-twOp?t+EM+7@2j%8}lArdg588%rgViu{Z7Z&)JTr(++M z`Vp33_G?%%4>FXr%yc?CVVR?aH2N_hf(%EM5{#$XLj#3V0*y~-@WnIHY>d<*qG9rJ zLEskCNnETYsn{E}ao?9QlcT#?Pa2Avj|5vn;__h~!#JWrm&0I!IcGgN0#Z{_fAr)? zkml1~9A(%Ugl=RL7GN505w? z9qK6^pT`-RrE*C|37)|hz4$`De`KwAqMgKzWz%W4^Y+2`xOs?ORL7U_W#+s;6b^@? zdwK^VyQ77Yy49ubB2EhVN7K*XIUUdAyd*ARnxv_xxlh{23;4PhU%Ro8CNq}FRDJ_5 zk_<*VZA`{e6O%VJMtih$hZfK~zoq(9BQEIpCSE33wuc2QW=#~c^JWw593>K%;G|`; zSlk>$lA3e$F(x^YFR$tNuB6bHIi9sf*;Zxqdpf=?n`KnPww*oJZ_s0QAW!qKV0r?V zbbKGL(@;EfCoQOIvBE}r%#^PpF{|TEkstvQvai7(O=Z(Db8lQ4r5ddEjNBx}iPan^ z9EY4sE}2bSRmx=IZVA^e`1#BEq}H52d{PO|!D+xw(zEB`7PYipkx*efoo_yd<83Ju`=ME#cD0mdKGIU)9`Qi)O&Jhp}?lYZH-sZ!Hd(VwzqGa z7q~1n#2zX6!@{?RF6I$8ZO2 z?&E3~b$X~vRbooiU+*t3duqRvBnM}e$Bfs-U|LNK~yo* z-1(SQgj;i9#C-B>xkNqd=w}yy%yjdM)}X9pPKrL8fzX0l~WpAiGFeo8Vmvu8Z0_aVMg*QC}eQ zTD2NvfZEjR5Lc4$CV1xPV4mPA3;{Ab%-;cFHwUK^iuZU?;=8T&$0%~oxOdtCX;A^m z;qKP!I|GL=qoMI}gFRy!6_K_a*d%=NJkU5pzsgy#%|tKH4o1U{f=%hWseG6n>=R7c zQA!weYlMX#qpXP*jPb^CrasPeCR8N4=n&m0L}DB79;LHBwBwVi)LW=?7Y@JCsQ#{8AyH#D^qfif!>tW&gy#>U7<|Q%Fmq)Bc2zK=pO4MaA!Dc zJanFZUbH=WgdOBFJx#8cP{xgwIeacWjlE4%sC@%ZSL4|nzB)bk6T3POG`;QH?%C+B z_qdy`VoKy?YQ1!R?zQ>5&M1qtUS!aAupal5pB3bvMVyTcoIGv54l_Z(b42$%t9FW* zU!dfRl)XU7m&x!~n6_8R(`jO#p|;nl?-Dh>!PYkMIEA zRdKUN*cm5oF7CggcwL5Ze2Xg=t({bfc2l2>E2-;2*7B=7^-!1WMVs@x=+3y`A%i?gQ4^& zC!AJ%J3VbEd3K6#C5ojFO<{w*`pz^OWscJO>cW}dUd;%BD_H#N3JDF+ZQwV2bNDS! z-eV$v&+|X9@%)jE=TF#(zjBKHjnm`r3y9t009x_;45cMG4w^@n=Wx-OtN#Y|_IfD* literal 3838 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 delta 709 zcma)4+fEZv6kVrhbm}lcxi&Ef3I%(E(TX=(ycI=oS}ub`d^=1}Y73b*b0P7miC3Q)i!$QJ5pOWr@baP3wCJuxV z_|<*Gt~++%y3+9t>%C*YbL&n$@HPS&$ee}@=2XlwO#jb7Q|d5qi-9)+pJ9ZE+cf*a zsTga!HEH{~cGSE-x2G7^Zs7b|T7!j1OJR~!@atxHjgN<)`I5SZby8`CKlv_O z4c{me%@c5XfyF~)Q(vGTW3+`a^8}MS>92?vySREA7fa; vb6Odr&I>FfLL&-ZVugCEgouLks*1cq>tE410ux253Qd%V5YPz8sM2!=al@s! diff --git a/judt/bin/judp/judpServer.class b/judt/bin/judp/judpServer.class index 6dfbda041138aa417e6207669d719a747b8e7fc1..f5bd88a297b8209a237d28b6417ef06a0b86a826 100644 GIT binary patch literal 3906 zcmaJ^`+pSG75`3l$%JJfF-Qmrsfs~1yM*PXR72Ae2(WZFKoSyzT07YcVZ&y2ot*_K zqHWchJ`|~_HP%OcVGBOOW0M-uzHR$=n8yCpf1sbX-+S+Dve_)n4|`|k-gEBve9!mX zbMyEAeDWE9?f9FH3JujGxuHx%{PbAPNz2jU*HANJo-`vV(;ki-92~I{u7=92oYt@^ zmK$;-NA~op^*!mt3CnHMpeM6EuIX^8c2q+Z-*O2no7E6VX1n|2X4bVF4a<_*lsRlU z-Ih5-r>XQXUoKvnTm*SN$wnzbM#!bGm%Q#Nw-~tFWAzj!M{5_WCc)*TXn1y zAZk*l?b`0(Xok$ zN~R2KMm6cpy6FrD_jr=&yCqhl5N4!ur_3H+fD%AHG2&ku> z29}{p;BOb}wlBrE(4k|OhSg=bw@z9q1G}+@Iqcun-4*THr(sPwg@~1HI`$U)6y>)g zmrM;=P8Ieu&e`enGaru6yfg9DwRivZ>39I0I3R$0n{qCfP=*x8K^nN|8Vz;xK^O0$8t;I`GeW< zr)FP0KlA+Me~i7P9%e6nG;{9lFQ=aU>d6~l-uQg>!uvWNTj06(xWf}w$Kx#6l6r04 z62Mt}Uj+LDaTYGBXCaU?cv38Qij`DMVt3BA#n~i9bOt{%@C?RCde(CHnAT|8CIi8v zEqzt^36GxnF7j{yKf`l6o?QU4=QNwZsDX2Mo-h+R$FXd;H#us>lc|(AYskj|Q35{~ zRrG>}wZQ|6Pwx3zIfEAsyd`OFtW2Q4~saLkPlz0= zxPx;ITfr3Ro)C@X3QMujNaR!i*O1q7oq8^D7&mRvwM7h*8o~va^G(GILzpRGo&_Vh zhTj_a1k;R!#Zri5fes76NN`p@Go%vK%<)KJuDB&BQ=XP0GudqO=JFC3R}yc<77f8N zMKHIYyyqyGR7k;U>-^(3p87rMoRhHjCPf>U?5o?*CUHbidQsc99C;bBvbcj?(Z?%S zB`QQ4=Tn7f>~dtQlp`CZ9N8v0Hi#PoM}u!GP)++9zHQ_v{)}2Jk6Wg&`YM_x_+EkA z_**Gw*Wz~h1$?_>&a#7Rgl$d8cOC0O*U+5DU3qMrw_YI;-bsATv|2B{7|I4)u$8tN z<+Po@M56h)PDJ!zXcBjawCiXN`GsTt><~ZqihbHb)7UW3IEim?{vx)5QZOhylT|* zZ4FkEvwB|Fnh>GQW?pf&AWGbaiMpG(`*AlOz&$dq5G{$_i%UG27-VFvWGsOp?%Pej z30QnO#+9q!`!8Ws=+M~zbi{eiJ|wO>+c4}A(o8~x)4~5sNO%gzyCf^EYbRkVTDnST zX)Q-fm!ySL9xV}uCTNK;umUaZOdQaD6Iym*9Xhyv4^emGAokL7AMVF~+DA#i0ZC1} zl;_|aHG_Br4r63wlB5cHS&l4Rred2%mycc)T|P-yy`XC=e56Z9ZXsi*@Tg)8?~$s~>C!;W#(C^BkKQxd+*(>OCQjk5zJ^@&ORFc$Xb@pM=U=*JY$6n>h=d8wZZ z;XGdUU#34Lk#(|+x+#rbisJ}{(NDqH6h@knXBh1xGTu6c!HYM{h+e@s5sI|?QL#dl zz^fSZFt>BHz+4$>q{ioqCm_E*#)uv-@>)5^VkLe_JY)i|mG{+F>gyT$8oPD7@Wed^0*iae}RDaIE_mK;YoZDCqW-i;VLU@YU9UqJT=ICKgZ+f9B=67 z`7hNA7HcLai7@~G literal 3702 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 diff --git a/judt/bin/udt/ClientSession.class b/judt/bin/udt/ClientSession.class index 5b0695927de05466a08f8025f52c4d071e2fd404..70dacc90bc7e8e2c117cce3392d02bf54b7704fd 100644 GIT binary patch literal 5042 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 literal 4727 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 HRQdk_`n%L! diff --git a/judt/bin/udt/ServerSession.class b/judt/bin/udt/ServerSession.class index e15a32bf2ac505ba7e22272c77f15a8b5020c928..9913a9443cbb5053a833a218ccee2b4680190a85 100644 GIT binary patch delta 140 zcmcbjc13N&5`lU@1}6r826u)a1|NoChA@UuhG-y}%@EE|!Vtkw$q>cR1{CRGh-H|_ z5YI4=A%S5DLlVPMhE#?%3~3D87}6PbGh{IA0qQuyki&42A&=n#Ljl7@hC+rL48;tO pfTlcSC}sG>P|on3p@QK*LnR{%Llq+rLp38WLnEWuW@SM`CII6YBk2GD delta 140 zcmcbjc13N&5`lVu1}BC926u*F1|NnHhA<$EW(a4-*KiX=JhbfoZVR-F?qXCHmK}() zz%NSZr0K*(UZgndC^Obwjnjn})kRJtPF;1=OwD*v4EFA>HBJA;_kRETKi~5_@B6*~ z<<^UB+O?G{R{_-X?0K!*=GHL8UY)y8Luh^@vdsvGJ$}Q=-NdSJ$U9_2oZjJ3*zjrG z!+jR+C2WJ9!=Bn~i3CEyhn*VgIH+@o!|Es7#(M`C)ESDM zw)D2{aCN%2T6vI2-WrMsmSOf<7*UP(0_||@&@)7PMS?&1ggrw|+VlCWI%}WfD{50l zL(_!LH<*3Xrllt2Tlg~e5<%bKaGjDU% zA85h~+G)b0OkOC<_WwV1GH0(j^(Hhdp%k~&N`afds2zna{-#bBHtR=`3=6=;c`m45 z3%}y;>hq#r&M8xI{h*PbQoSz9N9NJrC9x-yeNpz$LR)(gopb28fCn$ovxvpMO!_b3 z%NQn#ucNpYWndoVUGrGe6$d??0F5L-hY}!xkH(m0SGv^kV(0i2$6(^Lv?L4@Hpqm1 zhDz~fm25iFnSnB9qKa8)U^beWhYse$#RBxP5CIk;$YLC!1Cw-OnyWF#H8{gkoMSmI z@jhG?{5Pz^b=KfV)?$fu_?h?PHXp$9IP00jhiKsj+Swpixsfh5vYXA^#a0>JHjc29 zQ+!NJZs!ai=K`&~LN^-3>QoqPc{DXtF&U&MFP z`~Y_1dpMDTUotZzE@CrryIFfYSl!HvJ* zx`R~EA}CpgmXRgv9hCf&;#j+dVF%27m9MFmlH&2#iEZmHbCQVixU0G<%4xZWJ=Iap zoEM#>c<*z>9M}U3dtsNKJBNMZW_P^QwJ-~=9IYs?`n}BsXS+C&VP(*A_oq@ kO0Vj6=B9ltvb0(G2~Vl8vo`m1jFzABj6_YyCM3%9H~Fy)RR910 delta 1025 zcmZ8fOH5Q}6#hO??r^#4TtrQlGu!k9An%>R-|0mz;oO4H4jaBFm zChpz`P{ymb^g5>_l>r7dZc@KEJ;|Hdr2cW{F5E(x4dM1KJF=#~-R_BWhPxMAI=a|m zuod$OJ!D7L+r7PQAzMcYw;F6`hblD}?EdEg(D(Ck7FEo)%RvKzf`ZyVGbyjUcPjX!M&WBuvpXG9`3L^(&*uS1HbbCk)D@d+t(2( z-ne>0g9MOdOLY9jLk16XNNKJT>!`tFJTCsdc4T#1q)p88npWjE>S*CfgQrx$<>k5C zeXem%dyb`eg-X0ZH70KNXN3M=dhXsbCG`*J_!HT9r0TO8_*mV{^7C)?GHaO;#8hYi zqfuT{%RN8xiF)e^@Q@04%Npxur4$v!xH5{W+7T=mVdFjA3%b~R2R}&t(-?k=;X#aT zQG8e%#oPqQPJp&2K%XT*0{>#(C~7WGw5pe0YjA))Nail?VHc9|iR|+_@+1ePs$n|Q zkV6B7oQ85v$1<8&%XIkZLXb1j$qaPUjR9ujC}-geXJeRIxIquTqYrmz;lAL1W-cD` zBRparo-!ZLSb%XB;>{q7n8adgETPF#Sr zQ7%DykTy9mY(q$1Il}siy`Y3GWCRW*No0$Ca7trA*!&v5%8)y;5x>Dg3LavJ3%WrQE4@`@Az+HTG0$>=G3Txm%6- zyxRwf^#xUi9k|(%x=j7u7$=bn5>4IHDa?a-q}2f1o+-{ zCbxJO@+0B{p5_@*Fl9Ao)pE#P&Qh5O$(COesUQ#ct;>^pFfjP`8a_S;KB&U4;0(V5+ApigX diff --git a/judt/bin/udt/UDTClient.class b/judt/bin/udt/UDTClient.class index 432638aeba2d7ac2967c5c9510b2630bedb6c213..e434ffcba1d9ce624e5bf309f1499e6533f86d0f 100644 GIT binary patch literal 5511 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 D-L2<% literal 4826 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 diff --git a/judt/bin/udt/UDTInputStream$AppData.class b/judt/bin/udt/UDTInputStream$AppData.class index c5423c49c4137f966bf0f7a96625e838c678ec98..a4f45279c7bcd7f4bfa4928f4bec52cb70610c8d 100644 GIT binary patch delta 115 zcmcb{dyRL46$|e-1{Q|z44e!<82A`|PIhMrWBfaL9!m-nBhzFSR%<3kw#kmH0b-2Y z49tu?46Ka244jO73}Qf9f{}mna@I;UMiHQ}C<8mA7y~z>I0G-E1W-znL5fj|L7q{X QL7P#AL6=c>vK!k309jiSRsaA1 delta 115 zcmcb{dyRL46$|er1{Q|P44e#C82A{jPIhMrW4t+e9!m-n!@bEYtkz5nk0v{^28b~{ zXJBS{!NAJ!5~%bQgBXyOV0b-wIcudF!v~=7M+SC=PYm1)pBZ==z5u1ZGDtCeV~}U~ R&Y;ckgF%^)LAqW5f diff --git a/judt/bin/udt/UDTInputStream.class b/judt/bin/udt/UDTInputStream.class index a01d41cfde10989370e7ca068b2705e2e5e8c52d..fc7e6b7847d095bcc46996160ecc22a980a56704 100644 GIT binary patch literal 4031 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 R?^0%%Hln6I7AUJR{{z5k**X9K delta 944 zcmWNNeM}Wp7{-6k>0Un4OJV{dUzZD)doivA7lDm$3xk_YC@I}Qa}{V}8RT@!MLPfT zkIJ2DrL$Jhhk~V2vkb-Tk4lYP%PmnO#M)YZth80Gth2Md=iPgDp7-}Wliicu`zHK) zcKAnsPk|Q)SN()En;4@Zn%=YHB`@SHNGt6R~49?nf zdA+_#lDI%RQ-ruU+@2p)-z7X;#>W-X+^S4|C+OA{bDb!EQO(~hP>p+1= z&DkU>ha~w)Q7*F;AX`B~3K3SA5*1Oa2rZgNtD>~2jCReZLsdMg8hTaBCe^c94fej! zSYi`CH8WE&n;$-3(!w;glBx%oqa~E7jRrkPqaLDJOP!BpJnlH2QU~j`!g+bvmKJ{A z@R%d&bVOZ_Xcd`SO`g^`nr@11=TJNYf@Q60jrDulA=SJ1K z6|bHrT`xF8+sV;Oo^%YL7~Q+t#7E)DVkj0rf*#|-??Z`+fzkHvcBh5opEuD zlcuwd;T#d2XTE-*S`&6KvdwpaI88aT7oFLk?1Fg%xxcu{uO#b|W542*zq%p(HCdH(aYcdF# zOct6f7MX0iOb(ljpRFbrYx3-gI|q^rNH8H%O_*#`NP(GapDXFHPnLx3oYLyVa;H~8 zvZ=HyN^87Tculo^({**OtG837E#ABEn7eIdbh+;yH*4ZH6C=~yYx|=;zQsiu0J8ux V0JH!$0JQ)@0Ji{M0JxJT23-Vq54r#V delta 63 zcmV-F0Kor)4TBA^QUw8`lT!tzEv5hi0H^>B0I2{K0IC2S0Hy#Y0IUEi0IdKq0IvWt V0I&cy0I>i<0J8vI0JM`P23`Jq4~75$ diff --git a/judt/bin/udt/UDTSender.class b/judt/bin/udt/UDTSender.class index 758673298139fdef8901f0b0b5934f277284a8ea..a61009ab4573ae3f1c0689038d5cf9d7f18d90e8 100644 GIT binary patch literal 13543 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 DGh}3r literal 13118 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 Ee+Yi^dH?_b diff --git a/judt/bin/udt/UDTSocket.class b/judt/bin/udt/UDTSocket.class index e1e191dac7c325043700401d958714b255c8070d..51f2cc529c73da0936a8067b3e23467b9c103ac0 100644 GIT binary patch delta 108 zcmV-y0F(dZCFCWrd=L@80DJ(z0EPgw0FD5}0G9y9vyBiK0VT`;2ms9h5CF~q9stk) zBmmCn9stb% zBmm3+F96Q~HvrK9IsnoDLIBYKQ~=kL$`NP@+W-Xs+yDsx-IF^KauMVJ4glo<902A3 OApqw9CIIM@z7i%Zg&@ZO diff --git a/judt/bin/udt/packets/Acknowledgment2.class b/judt/bin/udt/packets/Acknowledgment2.class index ed0e891704cc008b7812349b0ab02cc3a1d52de2..b79ebbb92188c67df75c30c71336e205a8399dac 100644 GIT binary patch delta 103 zcmbQt^@NM-)W2Q(7#J8#7_2vPB{B&Krl*!Trle$+Waj53=6L3%Pe1=Jn yiJ67LZ1QeqHC;ajexM#621X#s%Am-g1f-c5%)z7ugC&sW0?LUnFf&*=NCE(+9~4>u delta 56 zcmaFDHJOX+)W2Q(7#J8#7_2sOB{EH}XG&n?*!+M=k4ch=!3-$D#9+=~0i?MY7#Tzu Jm>Db`BmuLP3mO0b diff --git a/judt/bin/udt/util/ReceiveBuffer.class b/judt/bin/udt/util/ReceiveBuffer.class index 1ad68c7a4720175490044ea201d0a6e07e7f91de..3f140eb16691487af870535f185bd6ad1b0b18b6 100644 GIT binary patch literal 4908 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 literal 3428 zcma)8`Bxj)75)ZE3@Br~1#E(2784=~+e&R?rz}np23Hg>u`n*AE*_)-#+GKpXk?7L z#BG*3X|^Wr5@&O|xr=*_+f#7ToHjr7oc_?$zo;i|`rS9O0<}X62fg?7?z``P-~H}= z{Qcj5`U`*q_??a#4Nc{opDg=!K6%Q@TJ}XNRi2%-JRM;To6egT&1Bwm=8`97&Rbbu zL+y;(*6{FCV{-EJk@2)sEc+SXv&=&0V6k|_^vymE2G_ZhZprp-*U_M*H8k1|S7ttA zEtD-MYaK5aW-O0;qZ*p$?YViYQ%g%+8hVC&Hn2I{@|A|fdiJL* zUh0{SKSo#ISy6A+LF0RtPv=PmzfqF!BbZdy+H;#ax zHF%>)V2^~cSHhSI!g$QUCTy0ieFpa909D{vi&b9fJ{Dh((W+&igmutB12#tSIC^z_ zQNy;XQr8N^Kp*-w)aR_MXBC(eiD)!FDn1SycmUCQdSt|Kf!N3rXFePr8 z#~Op+Y&Ut*vz>~j`*e)(^3O_vQn#JCRN2nwEUyk+_=H#-GjJRyc*rakEhnd82eWvOam9U~oOsf}DP$;Q-wixzc}<*MB@o|0SpwN;I~Cas zI=Q2k{{R-Tq~nr?&UI>`s#F7))paF%&M|pOILG$KoUX?NkuVg-NZuF?C$>|vJWe)b zd^3CDm|0ZZ>-g^7RH`(O&wK7-kg0Id&GWXyvGo1xY1}SYr`d-3;_C+z9ln&ciqfJ> zI=-i2=VvmP2I_g`qHpD@M#At523{1%n}y%1kv)@NisB`_qT^*g4)>+*ZcqkZm4elM z_qge}r6}w42L_(O>%5=3{`|JpC&{^H;D>TNYA%|#uRMq^0#-E~DHAsJ+WJ3;p=cbr zT|htBCF7R8tTke*B3$zh?-eH5N7IgDc|&=#RI-?<-?CQkrHPI!?=RXJZHTXY z9bW@>dCpSu)^OY+y`E!@G)A@N%b`X#TQ#zUtC8;rN1dLw;z52ka`jh)`3sy)+(AT46bbj(;PZ(AQHM2 z1e@(%fi>91MeGCE_1E5p5o{E~Vi6;b;?;xU#xNHh#e)$JU5%0M3`cq^o#EK?AujSi z35A`fdTT4w=Gu=L%QhmK=l%OIt;UeTJ)%;upYPuRHpYXrdK^2@OWPr$?4@--2KYNd z^vCf8CiuWjb8i-d^pe7P&KGb*@o|6xAigReKE8o(68#R0;aiH20kZjRaulY&4m{0S z1Xp-w8$z2tL3{X9^q_`1(Al5)@f{w12G271=V%n>>Uq(Iwu^I7jBv<2U)|mE+zP&* z;!22p6I&B2c&%5z3tzw8UVrVKDxcbIZuGQ&h&Mt=-Td?)y~1U{U328)HLQhkh!}@? zZ3A{9!z*LdfQ*OuDPzE5irfL?%3E)h z0d=nj+QTvnQ;Mm-LeX_Z6boHkH}4zk{u_2F`9--N5T#waj*TSoZ7HpRn_}I4yNWib zl_H~9U<@TzjL%vrvuZA~QWmM3OGLXwC0(Y1o>j<#TIsJKYeE;^Q`%@{`?{gDafSXj zAY}Xt-AsS@pA22Y`y?so2T8RCBv~D|XdBdREx!h?syhrdk5t)X2dx|~k}t8_!@~-* zmPt$!dib356;8zI4b%mFM#<=>XQVj<>1|TNeu-he%>MKW#rZ0MzP9SpJ(WwZs52VX zi(lZEmD>k7%IyujMFdLr!?!|$A#fjHcw?2jhPCbtg1t%e8vF{s<|r>jCw_xlsQ(Xx CKn`C3 diff --git a/judt/src/Test/TestClient.java b/judt/src/Test/TestClient.java index 7265de1..c7d65bf 100644 --- a/judt/src/Test/TestClient.java +++ b/judt/src/Test/TestClient.java @@ -7,19 +7,21 @@ public class TestClient { public static void main(String[] args) { + long num=0; while(true) { judpClient client=new judpClient(); - client.connect("192.168.64.128", 5555); - byte[]data="hello word".getBytes(); + client.connect("192.168.30.128", 5555); + byte[]data=("hello word "+num).getBytes(); client.sendData(data); client.close(); try { System.out.println("等待"); - TimeUnit.SECONDS.sleep(40); + TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } + num++; } } diff --git a/judt/src/Test/TestServer.java b/judt/src/Test/TestServer.java index 3a1202e..0b7050c 100644 --- a/judt/src/Test/TestServer.java +++ b/judt/src/Test/TestServer.java @@ -14,9 +14,9 @@ */ public class TestServer { public static void main(String[] args) { - - judpServer server=new judpServer("192.168.10.86",5555); - server.Start(); + //192.168.30.128 + judpServer server=new judpServer("192.168.30.128",5555); + server.start(); while(true) { judpSocket socket=server.accept(); @@ -61,7 +61,7 @@ public void run() { }} ); rec.setDaemon(true); - rec.setName(String.valueOf(socket.socketID)); + rec.setName(String.valueOf(socket.getID())); rec.start(); } diff --git a/judt/src/judp/ApplicationCode.java b/judt/src/judp/ApplicationCode.java index 102e11c..1ac79c2 100644 --- a/judt/src/judp/ApplicationCode.java +++ b/judt/src/judp/ApplicationCode.java @@ -79,7 +79,7 @@ static void CopySocketFile(File file, judpSocket target,int packagetLen) waitTime=(long)(speed*1000); } - System.out.println("sendFile_"+file.getName()+",socketID:"+target.socketID); + System.out.println("sendFile_"+file.getName()+",socketID:"+target.getID()); while(true){ try { c=fis.read(buf); diff --git a/judt/src/judp/DataStruct.java b/judt/src/judp/DataStruct.java new file mode 100644 index 0000000..9753922 --- /dev/null +++ b/judt/src/judp/DataStruct.java @@ -0,0 +1,88 @@ +/** + * + */ +package judp; + +import java.nio.ByteBuffer; + +/** + * @author jinyu + * + */ +public class DataStruct { +public int dataLen=0; +public byte[][] buffer=null; +public long id; +private volatile int sumNum=0; +private volatile int sumLen=0; +private byte[] result=null; +public DataStruct(int num) +{ + buffer=new byte[num][]; +} + +/** + * 整理数据 + * @return + */ +private boolean check() +{ + if(sumNum>=buffer.length) + { + //检查成功 + if(sumLen==dataLen) + { + //开始检查数据 + result=new byte[dataLen]; + ByteBuffer cur=ByteBuffer.wrap(result); + for(int i=0;i hash=new ConcurrentHashMap(); + private ConcurrentLinkedQueue queue=new ConcurrentLinkedQueue(); + + /** + * 添加数据 + * @param data + * @return + */ +public boolean addData(byte[] data) +{ + ByteBuffer buf=ByteBuffer.wrap(data); + long id=buf.getLong(); + int num=buf.getInt(); + DataStruct struct=hash.get(id); + if(struct==null) + { + struct=new DataStruct(num); + hash.put(id, struct); + } + boolean r= struct.addData(data); + if(r) + { + byte[]result =struct.getData(); + byte[] tmp=new byte[result.length]; + System.arraycopy(result, 0, tmp, 0, tmp.length); + queue.offer(tmp); + struct.clear(); + hash.remove(id); + } + return r; + +} + +/** + * 获取数据 + * @return + */ +public byte[] getData() +{ + return queue.poll(); +} +} diff --git a/judt/src/judp/PackagetSub.java b/judt/src/judp/PackagetSub.java new file mode 100644 index 0000000..6489a06 --- /dev/null +++ b/judt/src/judp/PackagetSub.java @@ -0,0 +1,100 @@ +/** + * + */ +package judp; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +/** + * @author jinyu + * + */ +public class PackagetSub { + private static AtomicLong sessionid=new AtomicLong(0); + public static int dataSzie=1472; + private static int bufsize=0; + private static int headLen=20; + + /** + * 分割数据 + * @param data + * @return + */ + public static byte[][] splitData(byte[]data) + { + if(bufsize==0) + { + bufsize=dataSzie-headLen; + } + long session=sessionid.incrementAndGet(); + int dataLen=data.length; + int num=data.length/bufsize+data.length%bufsize>0?1:0; + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(dataSzie); + for(int i=0;i0?1:0); + byte[][]sendData=new byte[num][]; + int index=0; + ByteBuffer buf=ByteBuffer.allocate(len); + for(int i=0;i hash=new ConcurrentHashMap(); +//private static final Logger logger=Logger.getLogger(SocketManager.class.getName()); + private ArrayBlockingQueue hasSocket=new ArrayBlockingQueue(1000); + private SocketControls (){ + startThread(); + + } + + /** + * 启动线程检查数据源 + */ + private void startThread() { + Thread processSocket=new Thread(new Runnable() { + + @Override + public void run() { + ArrayList list=new ArrayList(); + while(true) + { + for(Entry entry:hash.entrySet()) + { + UDTSocket socket= entry.getValue().getSocket(); + if(socket!=null) + { + try { + hasSocket.put(socket); + list.add(entry.getKey()); + + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + // + if(!list.isEmpty()) + { + //移除已经检查成功的socket + for(int i=0;i + * + */ +public class SocketReference extends WeakReference { + private long socketid=-1; + public SocketReference(T referent) { + super(referent); + + } + public SocketReference(T referent,long id) { + super(referent); + this.socketid=id; + } + @SuppressWarnings({ "rawtypes", "unchecked" }) + public SocketReference(T referent, long id, ReferenceQueue q) { + super(referent,q); + this.socketid=id; + } + public long getid() + { + return socketid; + } +} diff --git a/judt/src/judp/judpClient.java b/judt/src/judp/judpClient.java index 30413c4..aef95e3 100644 --- a/judt/src/judp/judpClient.java +++ b/judt/src/judp/judpClient.java @@ -7,6 +7,7 @@ import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; import udt.UDTClient; @@ -16,8 +17,10 @@ */ public class judpClient { private UDTClient client=null; - private final int bufSize=1500; + private final int bufSize=65535; private long sumLen=0; + private PackagetCombin pack=new PackagetCombin(); + public int dataLen=0; public judpClient(String lcoalIP,int port) { InetAddress addr = null; @@ -36,7 +39,7 @@ public judpClient(String lcoalIP,int port) e.printStackTrace(); } - SocketManager.getInstance().addGC(this,client); + } public judpClient() { @@ -47,7 +50,7 @@ public judpClient() } catch (UnknownHostException e) { e.printStackTrace(); } - SocketManager.getInstance().addGC(this,client); + } public judpClient(int port) { @@ -58,7 +61,7 @@ public judpClient(int port) } catch (UnknownHostException e) { e.printStackTrace(); } - SocketManager.getInstance().addGC(this,client); + } public boolean connect(String ip,int port) { @@ -90,9 +93,11 @@ public int sendData(byte[] data) if(client!=null) { try { + client.sendBlocking(data); r=data.length; sumLen+=r; + } catch (IOException e) { e.printStackTrace(); @@ -102,6 +107,30 @@ public int sendData(byte[] data) } return r; } + public int sendSplitData(byte[] data) + { + if(data==null) + { + return 0; + } + int r=0; + byte[][]sendData=null; + if(dataLen==0) + { + sendData=PackagetSub.splitData(data); + } + else + { + PackagetSub sub=new PackagetSub(); + sendData=sub.split(data, dataLen); + } + for(int i=0;i list=new ArrayList(); +private static final Logger logger=Logger.getLogger(judpGroupSocket.class.getName()); +public judpGroupSocket() +{ + +} + +/** + * 添加socket + * @param socket + */ +public void addSocket(UDTSocket socket) +{ + list.add(socket); +} + +/** + * 获取有数据socket + * 并且移除其它无用socket + * @return + */ +public UDTSocket getSocket() +{ + + int index=-1; + for( int i = 0 ; i < list.size() ; i++) { + try { + if(index==-1) + { + if(list.get(i).getInputStream().isHasData()) + { + //已经找到;其余的移除关 + index=i; + i=-1;//重新遍历 + } + } + else + { + // + if(i==index) + { + continue; + } + else + { + list.get(i).close(); + long id=list.get(i).getSession().getSocketID(); + list.get(i).getEndpoint().removeSession(id); + list.get(i).getReceiver().stop(); + list.get(i).getSender().stop(); + list.get(i).getSender().pause(); + logger.info("移除无用socket:"+id); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if(index!=-1) + { + return list.get(index); + } + return null; + +} +/** + * 清除所有socket + */ +public void clear() +{ + list.clear(); +} +} diff --git a/judt/src/judp/judpServer.java b/judt/src/judp/judpServer.java index 7ab2aa8..f316d7a 100644 --- a/judt/src/judp/judpServer.java +++ b/judt/src/judp/judpServer.java @@ -3,10 +3,10 @@ */ package judp; +import java.io.IOException; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; -import java.util.concurrent.SynchronousQueue; import java.util.logging.Level; import java.util.logging.Logger; @@ -20,9 +20,11 @@ */ public class judpServer { private UDTServerSocket server=null; -private final SynchronousQueue sessionHandoff=new SynchronousQueue(); +//private final SynchronousQueue sessionHandoff=new SynchronousQueue(); private boolean isStart=true; private boolean isSucess=true; +private boolean isRWMaster=true;//与默认值一致 +private boolean islagerRead=false; private static final Logger logger=Logger.getLogger(judpServer.class.getName()); /** @@ -33,6 +35,11 @@ public void close() isStart=false; server.getEndpoint().stop(); } + +/** + * + * @param port 端口 + */ public judpServer(int port) { @@ -46,6 +53,12 @@ public judpServer(int port) e.printStackTrace(); } } + +/** + * + * @param localIP 本地IP + * @param port 端口 + */ public judpServer(String localIP,int port) { try { @@ -64,7 +77,7 @@ public judpServer(String localIP,int port) /** * 启动接收 */ -public boolean Start() +public boolean start() { if(!isStart||!isSucess) { @@ -79,9 +92,14 @@ public void run() { { try { UDTSocket csocket= server.accept(); - judpSocket jsocket=new judpSocket(csocket); - sessionHandoff.put(jsocket); - SocketManager.getInstance().addGC(jsocket,csocket); + try { + csocket.getInputStream().setLargeRead(islagerRead); + csocket.getInputStream().resetBufMaster(isRWMaster); + } catch (IOException e) { + e.printStackTrace(); + } + + SocketControls.getInstance().addSocket(csocket); } catch (InterruptedException e) { e.printStackTrace(); } @@ -94,19 +112,41 @@ public void run() { serverThread.start(); return true; } +/** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * 设置大数据读取才有意义 + * @param isRead + */ +public void setBufferRW(boolean isRead) +{ + this.isRWMaster=isRead; + +} +/** + * 设置大数据读取 + * 默认 false + * @param islarge + */ +public void setLargeRead(boolean islarge) +{ + this.islagerRead=islarge; +} /** * 返回连接的socket */ public judpSocket accept() { -try { - judpSocket jsocket= sessionHandoff.take(); - return jsocket; -} catch (InterruptedException e) { - logger.info("judpSocket接收中断:"+e.getMessage()); - e.printStackTrace(); -} -return null; + UDTSocket socket=SocketControls.getInstance().getSocket(); + if(socket==null) + { + socket=SocketControls.getInstance().getSocket(); + } + judpSocket jsocket=new judpSocket(socket); + judpSocketManager.getInstance(socket.getEndpoint()).addSocket(jsocket); + return jsocket; + } } diff --git a/judt/src/judp/judpSocket.java b/judt/src/judp/judpSocket.java index 25e55fe..ebf6d0e 100644 --- a/judt/src/judp/judpSocket.java +++ b/judt/src/judp/judpSocket.java @@ -7,7 +7,6 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.TimeUnit; -import java.util.logging.Logger; import udt.UDTSession; import udt.UDTSocket; import udt.packets.Destination; @@ -16,21 +15,27 @@ * @author jinyu * *服务端返回的网络接口对象 + *保存socket并检查有数据的对象 */ public class judpSocket { -private final int bufSize=1500; +private int bufSize=65535; private UDTSocket socket=null; -private long start=System.currentTimeMillis(); private boolean isClose=false; -private long flushTime=0; -private final long waitDataLen=30*1000;//30秒 -private long readLen=0;//读取数据 private long sendLen=0;//发送数据 -public long socketID=0;//ID -private static final Logger logger=Logger.getLogger(judpSocket.class.getName()); +private long socketID=0;//ID +private Thread closeThread; +private final int waitClose=10*1000; +private PackagetCombin pack=new PackagetCombin(); +//private int readLen=0; +public int dataLen=0; +public void setRecBufferSize(int size) +{ + bufSize=size; +} public boolean getCloseState() { - return isClose; + //底层已经关闭 + return isClose|socket.isClose(); } public judpSocket(UDTSocket usocket) { @@ -38,8 +43,18 @@ public judpSocket(UDTSocket usocket) socketID=socket.getSession().getSocketID(); } +/** + * 获取ID + * @return + */ +public long getSocketID() +{ + return socketID; +} + /** * 关闭 + * 等待数据完成关闭 */ public void close() { @@ -47,29 +62,84 @@ public void close() //不能真实关闭 if(sendLen==0) { - //没有发送则可以直接关闭,不需要等待数据发送完成 - try { - socket.close(); - UDTSession serversession=socket.getEndpoint().removeSession(socketID); - if(serversession!=null) - { - serversession.getSocket().close(); - socket.getReceiver().stop(); - socket.getSender().stop(); - System.out.println("物理关闭socket:"+serversession.getSocketID()); - } - - serversession=null; - } catch (IOException e) { - e.printStackTrace(); - } + stop(); System.out.println("物理关闭socket"); } else { //有过发送数据则缓冲 - SocketManager.getInstance().add(socket); + //SocketManager.getInstance().add(socket); + + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(socket.getSender().isSenderEmpty()) + { + stop(); + break; + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + stop(); + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } +} + +/** + * 立即关闭 + */ +public void stop() +{ + //没有发送则可以直接关闭,不需要等待数据发送完成 + try { + socket.close(); + UDTSession serversession=socket.getEndpoint().removeSession(socketID); + if(serversession!=null) + { + serversession.getSocket().close(); + socket.getReceiver().stop(); + socket.getSender().stop(); + System.out.println("物理关闭socket:"+serversession.getSocketID()); + } + + serversession=null; + } catch (IOException e) { + e.printStackTrace(); } + System.out.println("物理关闭socket"); } /** @@ -78,20 +148,13 @@ public void close() */ public int readData(byte[]data) { - if(isClose) + if(getCloseState()) { return -1; } try { int r=socket.getInputStream().read(data); - readLen+=r; - flushTime=System.currentTimeMillis(); - if(flushTime-start>waitDataLen&&readLen==0) - { - //等待时间长度,没有发送过接收过数据,则退出 - logger.info("缓冲时间到退出读取:"+socketID); - return -1; - } + //readLen+=r; return r; } catch (IOException e) { e.printStackTrace(); @@ -102,84 +165,57 @@ public int readData(byte[]data) /** * 读取全部数据 */ -public byte[] readData() +public byte[] readALL() { byte[] result=null; if(socket!=null) { byte[] readBytes=new byte[bufSize];//接收区 - byte[] buf=new byte[bufSize];//数据区 - int index=0; int r=0; - try { - while(true) - { - if(isClose) - { - return null; + while(true) + { + if(getCloseState()) + { + return null; + } + r=readData(readBytes); + if(r==-1) + { + result=pack.getData(); + break; + } + else + { + // readLen+=r; + if(r==0) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + + continue; + } catch (InterruptedException e) { + e.printStackTrace(); } - r=socket.getInputStream().read(readBytes); - if(r==-1) - { - break; - } - else - { - readLen+=r; - if(r==0) - { - try { - TimeUnit.MILLISECONDS.sleep(100); - flushTime=System.currentTimeMillis(); - if(flushTime-start>waitDataLen&&readLen==0) - { - //没有使用过数据 - break; - } - continue; - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if(r<=bufSize) - { - //result=new byte[r]; - //System.arraycopy(readBytes, 0, result, 0, r); - if(index+r hashMap=new WeakHashMap (); + private final HashMap,Long> map=new HashMap,Long> (); + private UDPEndPoint endPoint=null; + private static judpSocketManager instance=null; + private judpSocketManager (UDPEndPoint point){ + + startGC(); + this.endPoint=point; + + } + + /** + * 清理没有使用的judpSocket + */ + private void startGC() { + Thread clearSession=new Thread(new Runnable() { + + @SuppressWarnings("unchecked") + @Override + public void run() { + while(true) + { + + SocketReference k; + try { + while((k = (SocketReference) q.remove()) != null) { + try + { + map.remove(k); + long id=k.getid(); + UDTSession serversession=endPoint.removeSession(id); + if(serversession!=null) + { + serversession.getSocket().close(); + serversession.getSocket().getReceiver().stop(); + serversession.getSocket().getSender().stop(); + logger.info("清除socket:"+id); + } + } + catch(Exception ex) + { + logger.warning("清除session:"+ex.getMessage()); + } + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + + } + + }); + clearSession.setDaemon(true); + clearSession.setName("clearSession"); + clearSession.start(); + + } + + /** + * 单例 + * @param point + * @return + */ + public static synchronized judpSocketManager getInstance(UDPEndPoint point) { + + if (instance == null) { + + instance = new judpSocketManager(point); + + } + return instance; + } + + /** + * 添加judpSocket + * @param socket + */ + public void addSocket(judpSocket socket) + { + SocketReference tmp=new SocketReference(socket,socket.getSocketID(),q); + hashMap.put(socket, socket.getSocketID()); + map.put(tmp, socket.getSocketID()); + if(num%10==0) + { + System.gc(); + } + num++; + } +} diff --git a/judt/src/net/File/FileMonitor.java b/judt/src/net/File/FileMonitor.java new file mode 100644 index 0000000..c577d9f --- /dev/null +++ b/judt/src/net/File/FileMonitor.java @@ -0,0 +1,16 @@ +/** + * + */ +package net.File; + + +import java.nio.file.WatchEvent.Kind; + +/** + * @author jinyu + * + */ +public class FileMonitor { +public String file; +public Kind kind; +} diff --git a/judt/src/net/File/FilesWatch.java b/judt/src/net/File/FilesWatch.java new file mode 100644 index 0000000..d8a7e98 --- /dev/null +++ b/judt/src/net/File/FilesWatch.java @@ -0,0 +1,99 @@ +/** + * + */ +package net.File; + +import java.io.IOException; + +import java.nio.file.FileSystems; +import java.nio.file.Paths; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * @author jinyu + * + */ +public class FilesWatch { + +private WatchService watcher = null; + private String dir; + private Thread checkThread=null; + private LinkedBlockingQueue queue=new LinkedBlockingQueue(); + private boolean isStop=false; + public FilesWatch() + { + try { + watcher = FileSystems.getDefault().newWatchService(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + public void setWatch(String dir) + { + this.dir=dir; + } + public void stop() + { + isStop=true; + } + public FileMonitor take() + { + try { + return queue.take(); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + return null; + } + public void start() + { + checkThread =new Thread(new Runnable() { + + @Override + public void run() { + try + { + Paths.get(dir).register(watcher, + StandardWatchEventKinds.ENTRY_CREATE, + StandardWatchEventKinds.ENTRY_DELETE, + StandardWatchEventKinds.ENTRY_MODIFY); + } + catch(Exception ex) + { + + } + while (!isStop) { + WatchKey key; + try { + key = watcher.take(); + for (WatchEvent event: key.pollEvents()) { + FileMonitor e=new FileMonitor(); + e.file=event.context().toString(); + e.kind=event.kind(); + queue.put(e); + } + + boolean valid = key.reset(); + if (!valid) { + break; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + + + }); + checkThread.setDaemon(true); + checkThread.setName("monitor"); + checkThread.start(); +} +} diff --git a/judt/src/net/File/PackagetCharSet.java b/judt/src/net/File/PackagetCharSet.java new file mode 100644 index 0000000..094419b --- /dev/null +++ b/judt/src/net/File/PackagetCharSet.java @@ -0,0 +1,12 @@ +/** + * + */ +package net.File; + +/** + * @author jinyu + * + */ +public class PackagetCharSet { +public static String CharSet="UTF-8"; +} diff --git a/judt/src/net/File/ReadXml.java b/judt/src/net/File/ReadXml.java new file mode 100644 index 0000000..1ea849c --- /dev/null +++ b/judt/src/net/File/ReadXml.java @@ -0,0 +1,104 @@ +/** + * + */ +package net.File; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; +import java.net.URL; +import java.net.URLDecoder; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * @author jinyu + * + */ +public class ReadXml { + public static String getPath() { + URL url = ReadXml.class.getProtectionDomain().getCodeSource().getLocation(); + String filePath = null; + try { + filePath = URLDecoder.decode(url.getPath(), "utf-8");// 转化为utf-8编码 + } catch (Exception e) { + e.printStackTrace(); + } + if (filePath.endsWith(".jar")) {// 可执行jar包运行的结果里包含".jar" + // 截取路径中的jar包名 + filePath = filePath.substring(0, filePath.lastIndexOf("/") + 1); + } + + File file = new File(filePath); + + // /If this abstract pathname is already absolute, then the pathname + // string is simply returned as if by the getPath method. If this + // abstract pathname is the empty abstract pathname then the pathname + // string of the current user directory, which is named by the system + // property user.dir, is returned. + filePath = file.getAbsolutePath();//得到windows下的正确路径 + return filePath; + } +public String readXml(String file) +{ + File f=new File(file); + if(!f.exists()) + { + return ""; + } + // + String xmlStr= readFile(file).trim(); + StringReader sr = new StringReader(xmlStr); + InputSource is = new InputSource(sr); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Document doc = null; + try { + doc = (Document) builder.parse(is); + } catch (SAXException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + NodeList list=doc.getElementsByTagName("IP"); + String ip= list.item(0).getTextContent(); + list=doc.getElementsByTagName("Port"); + String port=list.item(0).getTextContent(); + list=doc.getElementsByTagName("Dir"); + String dir=list.item(0).getTextContent(); + String strxml=ip+","+port+","+dir; + return strxml; + } +private String readFile(String file) +{ + StringBuilder result = new StringBuilder(); + try{ + BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 + String s = null; + while((s = br.readLine())!=null){//使用readLine方法,一次读一行 + result.append(System.lineSeparator()+s); + } + br.close(); + }catch(Exception e){ + e.printStackTrace(); + } + return result.toString(); +} +} diff --git a/judt/src/net/File/RecviceFiles.java b/judt/src/net/File/RecviceFiles.java new file mode 100644 index 0000000..f13f92e --- /dev/null +++ b/judt/src/net/File/RecviceFiles.java @@ -0,0 +1,251 @@ +/** + * + */ +package net.File; + + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpServer; +import judp.judpSocket; + + + +/** + * 接收文件 + * @author jinyu + * + */ +public class RecviceFiles { +private judpServer server=null; +private Thread recThread=null; +private static Logger log=Logger.getLogger(RecviceFiles.class.getName()); +private String dir=""; +private ExecutorService pools = Executors.newCachedThreadPool(); +public void setDir(String dir) +{ + this.dir=dir; +} +public boolean start(String host,int port) +{ + File cur=new File(dir); + if(!cur.exists()) + { + cur.mkdir(); + } + server=new judpServer(host, port); + boolean r= server.start(); + recThread=new Thread(new Runnable() { + + private ConcurrentHashMap fileInfo=new ConcurrentHashMap(); + private ConcurrentHashMap hashFile=new ConcurrentHashMap(); + + @Override + public void run() { + + while(true) + { + + judpSocket ss= server.accept(); + pools.execute(new Runnable() { + String fileName=""; + private long sumBytes=0; + private ConcurrentLinkedQueue recQueue=new ConcurrentLinkedQueue(); + private boolean isStop=false; + /** + * 写入文件 + * @param data + * @return + */ + private boolean writeFile(byte[] data) + { + try + { + String filePath=dir+"/"+fileName; + FileOutputStream fs=new FileOutputStream(filePath+".tmp",true); + DataOutputStream out=new DataOutputStream(fs); + out.write(data); + out.close(); + File f=new File(filePath+".tmp"); + long flen=fileInfo.get(fileName); + if(flen==f.length()) + { + //完成 + log.info(fileName+"接收完成"); + fileInfo.remove(fileName); + hashFile.remove(fileName); + // + f.renameTo(new File(filePath)); //改名 + return true; + } + log.info(fileName+":"+f.length()); + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + /** + * 接收数据写入文件 + */ + private void recData() + { + Thread fileW=new Thread(new Runnable() { + + @Override + public void run() { + while(!isStop) + { + byte[]tmp=recQueue.poll(); + if(tmp==null) + { + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + + e.printStackTrace(); + } + continue; + } + if(writeFile(tmp)) + { + isStop=true; + break; + } + } + // + recQueue.clear(); + System.gc(); + } + + }); + fileW.setDaemon(true); + fileW.setName(fileName+"_Thread"); + fileW.start(); + } + @Override + public void run() { + byte[] recData=new byte[65535]; + long lastTime=System.currentTimeMillis(); + long speed=0; + while(!isStop) + { + int r= ss.readData(recData); + if(r==0) + { + continue; + } + else if(r==-1) + { + break; + } + //按照Ip + String key=ss.getRemoteHost()+ss.getRemoteHost(); + if (hashFile.containsKey(key)) { + //说明是接收数据 + byte[] tmp=new byte[r]; + System.arraycopy(recData, 0, tmp, 0, r); + sumBytes+=r; + recQueue.offer(tmp); + // + try + { + // + long timespan=System.currentTimeMillis()-lastTime; + if(timespan>1000) + { + speed=sumBytes/(timespan/1000); + sumBytes=0;//已经计算 + lastTime=System.currentTimeMillis(); + } + else + { + //不到1s + } + + } + catch(Exception ex) + { + + } + log.info("文件接收速度(M/S):"+speed/1024/1024); + } + else + { + //信息 + String info = null; + try { + info = new String(recData,0,r,PackagetCharSet.CharSet); + } catch (UnsupportedEncodingException e) { + + e.printStackTrace(); + } + String[] finfo=info.split(","); + if(finfo!=null&&finfo.length==2) + { + String name=""; + long len=0; + if(finfo[0].startsWith("File:")) + { + name=finfo[0].substring(5); + } + if(finfo[1].startsWith("Length:")) + { + String flen=finfo[1].substring(7); + len=Long.valueOf(flen); + } + hashFile.put(key, 1L); + fileInfo.put(name, len); + fileName=name; + if(len==0) + { + //空文件不会有数据 + byte[]tmp=name.getBytes(); + ByteBuffer buf=ByteBuffer.allocate(tmp.length+4); + buf.putInt(tmp.length); + buf.put(tmp); + writeFile(buf.array()); + break; + } + else + { + recData(); + } + try { + ss.sendData(("initServer:"+name).getBytes(PackagetCharSet.CharSet)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + ss.setLargeRead(true); + log.info("返回信息"); + + } + } + } + // + ss.close(); + + } + }); + + } + } + }); + recThread.setDaemon(true); + recThread.setName("recfiles"); + recThread.start(); +return r; +} +} diff --git a/judt/src/net/File/SendFiles.java b/judt/src/net/File/SendFiles.java new file mode 100644 index 0000000..4c9d7a8 --- /dev/null +++ b/judt/src/net/File/SendFiles.java @@ -0,0 +1,150 @@ +/** + * + */ +package net.File; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import judp.judpClient; + + + + +/** + * 发送文件 + * @author jinyu + * + */ +public class SendFiles { +private judpClient client=null; +private final int bufSize=10*1024*1024; +private String remoteHost=""; +private int remotePort=0; +private static Logger log=Logger.getLogger(SendFiles.class.getName()); + public SendFiles(String host,int port) + { + this.remoteHost=host; + this.remotePort=port; + } +public void sendFile(String path) +{ + File dir=new File(path); + if(!dir.exists()) + { + return; + } + // + File[] f=null; + if(dir.isDirectory()) + { + f=dir.listFiles(); + } + else + { + f=new File[] {dir}; + } + readSend(f); +} +private void readSend(File[]files) +{ + if(files==null||files.length==0) + { + return; + } + // + for(int i=0;i1000) + { + //10秒后超时 + client.close(); + log.warning("超时,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + if(r==0&&client.isClose()) + { + //超时 + client.close(); + log.warning("接收端没有回执,发送文件失败:"+f.getName()); + buf=null; + System.gc(); + return; + } + else if(r>0) + { + break; + } + } + String serverinfp=new String(infobytes,0,r,PackagetCharSet.CharSet); + String rsp="initServer:"+f.getName(); + if(!serverinfp.equals(rsp)) + { + client.close(); + return; + } + log.info("读取文件"); + dis = new DataInputStream(new FileInputStream(f)); + int count=0; + long startTime=System.currentTimeMillis(); + while((count=dis.read(buf,0, bufSize))!=-1) + { + + if(count==bufSize) + { + client.sendData(buf); + log.info("发送:"+f.getName()+","+bufSize); + } + else + { + byte[] tmp=new byte[count]; + System.arraycopy(buf, 0, tmp, 0, tmp.length); + client.sendData(tmp); + log.info("发送:"+f.getName()+","+count); + } + + } + long endTime=System.currentTimeMillis(); + client.close(); + dis.close(); + long speed=fLen/((endTime-startTime)/1000); + log.info("发送完成:"+f.getName()+",平均速度(M/S):"+speed/1024/1024); + + } + catch(Exception ex) + { + + } + +} +} diff --git a/judt/src/net/File/TestRecFiles.java b/judt/src/net/File/TestRecFiles.java new file mode 100644 index 0000000..7652fae --- /dev/null +++ b/judt/src/net/File/TestRecFiles.java @@ -0,0 +1,43 @@ +/** + * + */ +package net.File; + +import java.io.IOException; +import java.util.logging.Logger; + + + + +/** + * @author jinyu + * + */ +public class TestRecFiles { + private static Logger log=Logger.getLogger(TestRecFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //192.168.30.128 + ReadXml rd=new ReadXml(); + String xml= rd.readXml(ReadXml.getPath()+"/config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + RecviceFiles rec=new RecviceFiles(); + String dir=config[2]; + rec.setDir(dir); + rec.start(config[0], Integer.valueOf(config[1])); + log.info("启动接收文件"); + try { + System.in.read(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/judt/src/net/File/TestSendFiles.java b/judt/src/net/File/TestSendFiles.java new file mode 100644 index 0000000..d904b6a --- /dev/null +++ b/judt/src/net/File/TestSendFiles.java @@ -0,0 +1,52 @@ +/** + * + */ +package net.File; + + +import java.util.logging.Logger; + +import net.File.FileMonitor; +import net.File.FilesWatch; + + + + +/** + * @author jinyu + * + */ +public class TestSendFiles { + private static Logger log=Logger.getLogger(TestSendFiles.class.getName()); + /** + * @param args + */ + public static void main(String[] args) { + //SendFiles send=new SendFiles("192.168.9.152", 5555); + //192.168.30.128 + + ReadXml rd=new ReadXml(); + String xml= rd.readXml(ReadXml.getPath()+"/Config.xml"); + String[] config=null; + if(xml!=null) + { + config=xml.split(","); + } + SendFiles send=new SendFiles(config[0], Integer.valueOf(config[1])); + FilesWatch watch=new FilesWatch(); + String dir=config[2]; + watch.setWatch(dir); + watch.start(); + while(true) + { + FileMonitor ff= watch.take(); + log.info(ff.file); + if(ff.file.endsWith(".tmp")) + { + continue; + } + send.sendFile(dir+"/"+ff.file); + } + } + +} diff --git a/judt/src/udt/ClientSession.java b/judt/src/udt/ClientSession.java index e62b557..959b0de 100644 --- a/judt/src/udt/ClientSession.java +++ b/judt/src/udt/ClientSession.java @@ -51,7 +51,7 @@ public class ClientSession extends UDTSession { private static final Logger logger=Logger.getLogger(ClientSession.class.getName()); private UDPEndPoint endPoint; - + public volatile int connectNum=0;//cd public ClientSession(UDPEndPoint endPoint, Destination dest)throws SocketException{ super("ClientSession localPort="+endPoint.getLocalPort(),dest); this.endPoint=endPoint; @@ -109,10 +109,11 @@ public void received(UDTPacket packet, Destination peer) { long peerSocketID=hs.getSocketID(); destination.setSocketID(peerSocketID); setState(ready); + Thread.sleep(50); this.setInitialSequenceNumber(hs.getInitialSeqNo());//cd 必须重置 + System.out.println("初始序列置回2:"+this.getInitialSequenceNumber()); socket=new UDTSocket(endPoint,this); - }catch(Exception ex){ logger.log(Level.WARNING,"Error creating socket",ex); setState(invalid); @@ -161,6 +162,7 @@ protected void sendHandShake()throws IOException{ handshake.setSession(this); logger.info("Sending "+handshake); endPoint.doSend(handshake); + connectNum++; } //2nd handshake for connect diff --git a/judt/src/udt/ServerSession.java b/judt/src/udt/ServerSession.java index 1c2c9b9..253810a 100644 --- a/judt/src/udt/ServerSession.java +++ b/judt/src/udt/ServerSession.java @@ -75,7 +75,6 @@ public void received(UDTPacket packet, Destination peer){ if (getState()<=ready){ destination.setSocketID(connectionHandshake.getSocketID()); - if(getState()<=handshaking){ setState(handshaking); } @@ -126,6 +125,7 @@ public void received(UDTPacket packet, Destination peer){ else{ try{ + if(packet.forSender()){ socket.getSender().receive(packet); }else{ diff --git a/judt/src/udt/UDPEndPoint.java b/judt/src/udt/UDPEndPoint.java index 2db8a93..293f808 100644 --- a/judt/src/udt/UDPEndPoint.java +++ b/judt/src/udt/UDPEndPoint.java @@ -210,6 +210,13 @@ public void addSession(Long destinationID,UDTSession session){ public UDTSession getSession(Long destinationID){ return sessions.get(destinationID); } + + /** + * 移除session + * cd + * @param socketid + * @return + */ public UDTSession removeSession(long socketid) { //cd @@ -285,7 +292,7 @@ protected void doReceive()throws IOException{ } } peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); - session.received(packet,peer); + session.received(packet,peer); } } else{ @@ -296,7 +303,7 @@ protected void doReceive()throws IOException{ session=lastSession; } else{ - session=sessions.get(dest); + session=sessions.get(dest);//cd lastSession=session; lastDestID=dest; } @@ -308,10 +315,19 @@ protected void doReceive()throws IOException{ } else{ session.received(packet,peer); + } } }catch(SocketException ex){ - logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + if(ex.getMessage().equals("socket closed")&&stopped) + { + //cd + //已经正常关闭 + } + else + { + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + } }catch(SocketTimeoutException ste){ //can safely ignore... we will retry until the endpoint is stopped } diff --git a/judt/src/udt/UDTClient.java b/judt/src/udt/UDTClient.java index f298118..80ba986 100644 --- a/judt/src/udt/UDTClient.java +++ b/judt/src/udt/UDTClient.java @@ -50,7 +50,8 @@ public class UDTClient { private final UDPEndPoint clientEndpoint; private ClientSession clientSession; private boolean close=false; - + private Thread closeThread=null;//cd + private final int waitClose=10*1000; public UDTClient(InetAddress address, int localport)throws SocketException, UnknownHostException{ //create endpoint clientEndpoint=new UDPEndPoint(address,localport); @@ -99,10 +100,18 @@ public void connect(String host, int port)throws InterruptedException, UnknownHo * @throws InterruptedException */ public void send(byte[]data)throws IOException, InterruptedException{ + if(close) + { + return;//cd + } clientSession.getSocket().doWrite(data); } public void sendBlocking(byte[]data)throws IOException, InterruptedException{ + if(close) + { + return;//cd + } clientSession.getSocket().doWriteBlocking(data); } @@ -166,6 +175,70 @@ public long getSocketID() return clientSession.getSocketID(); } + /** + * 同步关闭 + * 等待数据发送完成后再关闭 + * 但是只等待10ss + */ + public synchronized void close() + { + close=true; + if(closeThread==null) + { + closeThread=new Thread(new Runnable() { + + @Override + public void run() { + int num=0; + while(true) + { + if(clientSession.getSocket().getSender().isSenderEmpty()) + { + try { + shutdown(); + break; + } catch (IOException e) { + + e.printStackTrace(); + } + } + else + { + try { + TimeUnit.MILLISECONDS.sleep(100); + num++; + if(waitClose<=num*100) + { + try { + shutdown(); + } catch (IOException e) { + + e.printStackTrace(); + } + break; + } + } catch (InterruptedException e) { + + e.printStackTrace(); + } + } + } + + } + + }); + closeThread.setDaemon(true); + closeThread.setName("closeThread"); + } + if(closeThread.isAlive()) + { + return; + } + else + { + closeThread.start(); + } + } public boolean isClose() { diff --git a/judt/src/udt/UDTCongestionControl.java b/judt/src/udt/UDTCongestionControl.java index fea7c51..ecf5836 100644 --- a/judt/src/udt/UDTCongestionControl.java +++ b/judt/src/udt/UDTCongestionControl.java @@ -151,7 +151,7 @@ public void onACK(long ackSeqno){ packetSendingPeriod=1000000.0/packetArrivalRate; } else{ - packetSendingPeriod=congestionWindowSize/(roundTripTime+Util.getSYNTimeD()); + packetSendingPeriod=(double)congestionWindowSize/(roundTripTime+Util.getSYNTimeD()); } } diff --git a/judt/src/udt/UDTInputStream.java b/judt/src/udt/UDTInputStream.java index c1c6e72..5ba7fa4 100644 --- a/judt/src/udt/UDTInputStream.java +++ b/judt/src/udt/UDTInputStream.java @@ -59,6 +59,10 @@ public class UDTInputStream extends InputStream { private volatile boolean closed=false; private volatile boolean blocking=true; + + private volatile boolean hasData=false;//cd + + /** * create a new {@link UDTInputStream} connected to the given socket @@ -166,6 +170,7 @@ private void updateCurrentChunk(boolean block)throws IOException{ * */ protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + hasData=true;//cd return receiveBuffer.offer(new AppData(sequenceNumber,data)); } @@ -199,7 +204,38 @@ public int getReceiveBufferSize(){ protected void noMoreData()throws IOException{ expectMoreData.set(false); } - + + /** + * 判断有没有数据进来 + * cd + * @return + */ + public boolean isHasData() + { + return hasData; + } + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + receiveBuffer.resetBufMaster(isRead); + + } + + /** + * 设置大数据读取 + * 默认 false + * @param islarge + */ + public void setLargeRead(boolean islarge) + { + receiveBuffer.setLargeRead(islarge); + } /** * used for storing application data and the associated * sequence number in the queue in ascending order @@ -248,8 +284,8 @@ public boolean equals(Object obj) { return false; return true; } - - + + } } diff --git a/judt/src/udt/UDTReceiver.java b/judt/src/udt/UDTReceiver.java index 3051801..9100a21 100644 --- a/judt/src/udt/UDTReceiver.java +++ b/judt/src/udt/UDTReceiver.java @@ -155,6 +155,8 @@ public class UDTReceiver { private final boolean storeStatistics; + + /** * create a receiver with a valid {@link UDTSession} * @param session @@ -242,6 +244,7 @@ public void receiverAlgorithm()throws InterruptedException,IOException{ if(nextNAK0){ sendNAK(currentSequenceNumber); + } else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ /*(6.b).if the sequence number is less than LRSN,remove it from * the receiver's loss list */ receiverLossList.remove(currentSequenceNumber); + } - + statistics.incNumberOfReceivedDataPackets(); //(7).Update the LRSN @@ -476,6 +483,7 @@ protected void sendNAK(ListsequenceNumbers)throws IOException{ nAckPacket.setDestinationID(session.getDestination().getSocketID()); endpoint.doSend(nAckPacket); statistics.incNumberOfNAKSent(); + } protected long sendLightAcknowledgment(long ackNumber)throws IOException{ @@ -535,7 +543,6 @@ protected void onAck2PacketReceived(Acknowledgment2 ack2){ if(entry!=null){ long ackNumber=entry.getAckNumber(); largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); - long rtt=entry.getAge(); if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; else roundTripTime = rtt; diff --git a/judt/src/udt/UDTSender.java b/judt/src/udt/UDTSender.java index 599e7be..f5f44d0 100644 --- a/judt/src/udt/UDTSender.java +++ b/judt/src/udt/UDTSender.java @@ -117,6 +117,10 @@ public class UDTSender { private final AtomicReference waitForSeqAckLatch=new AtomicReference(); private final boolean storeStatistics; + + // cd + private volatile int bufferNum=0; + private volatile boolean isModify=true; public UDTSender(UDTSession session,UDPEndPoint endpoint){ if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); @@ -246,7 +250,31 @@ else if (p instanceof KeepAlive) { protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ waitForAckLatch.get().countDown(); waitForSeqAckLatch.get().countDown(); - + //cd + long ackNumber=acknowledgement.getAckNumber(); + // cd + if(this.session instanceof ClientSession) + { + //cd + if(this.isModify) + { + //已经发送过10000包,不用再修正,认为接收方已经关闭 + if(bufferNum<10000) + { + if(ackNumber/100000!=this.session.getInitialSequenceNumber()/100000) + { + //认为不同段的seqNo,则不是通信的接收方session + statistics.incNumberOfACKReceived(); + if(storeStatistics)statistics.storeParameters(); + return; + } + } + else + { + this.isModify=false;//不用再修正 + } + } + } CongestionControl cc=session.getCongestionControl(); long rtt=acknowledgement.getRoundTripTime(); if(rtt>0){ @@ -261,8 +289,9 @@ protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); } - long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); //need to remove all sequence numbers up the ack number from the sendBuffer boolean removed=false; @@ -272,11 +301,15 @@ protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ } if(removed){ unacknowledged.decrementAndGet(); + bufferNum++;//cd } } - lastAckSequenceNumber=Math.max(lastAckSequenceNumber, ackNumber); + + lastAckSequenceNumber=Math.max(lastAckSequenceNumber, ackNumber); + //send ACK2 packet to the receiver sendAck2(ackNumber); + // statistics.incNumberOfACKReceived(); if(storeStatistics)statistics.storeParameters(); } @@ -328,6 +361,7 @@ public void senderAlgorithm()throws InterruptedException, IOException{ if (!senderLossList.isEmpty()) { Long entry=senderLossList.getFirstEntry(); handleResubmit(entry); + logger.info("senderLossList:"+entry); } else @@ -470,4 +504,21 @@ public void pause(){ startLatch=new CountDownLatch(1); paused=true; } + + /** + * 发送的数据清空 + * cd + * @return + */ + public boolean isSenderEmpty() + { + if(senderLossList.isEmpty()&&sendBuffer.isEmpty()&&sendQueue.isEmpty()) + { + return true; + } + else + { + return false; + } + } } diff --git a/judt/src/udt/UDTSession.java b/judt/src/udt/UDTSession.java index d7a45f2..0ff9dfe 100644 --- a/judt/src/udt/UDTSession.java +++ b/judt/src/udt/UDTSession.java @@ -210,7 +210,7 @@ public long getSocketID(){ public synchronized long getInitialSequenceNumber(){ if(initialSequenceNumber==null){ - initialSequenceNumber=1l; //TODO must be random? + initialSequenceNumber=1l; } return initialSequenceNumber; } diff --git a/judt/src/udt/UDTSocket.java b/judt/src/udt/UDTSocket.java index d47ea35..c070e4a 100644 --- a/judt/src/udt/UDTSocket.java +++ b/judt/src/udt/UDTSocket.java @@ -186,12 +186,15 @@ protected void doWrite(byte[]data, int offset, int length, int timeout, TimeUnit packet.setSession(session); packet.setDestinationID(session.getDestination().getSocketID()); packet.setData(chunk); + //put the packet into the send queue if(!sender.sendUdtPacket(packet, timeout, units)){ throw new IOException("Queue full"); } + } if(length>0)active=true; + } /** * will block until the outstanding packets have really been sent out diff --git a/judt/src/udt/packets/Acknowledgment2.java b/judt/src/udt/packets/Acknowledgment2.java index 1e881bc..e16a34c 100644 --- a/judt/src/udt/packets/Acknowledgment2.java +++ b/judt/src/udt/packets/Acknowledgment2.java @@ -62,7 +62,7 @@ public void setAckSequenceNumber(long ackSequenceNumber) { void decode(byte[]data){ } - + @Override public boolean forSender(){ return false; @@ -73,6 +73,11 @@ public boolean forSender(){ public byte[] encodeControlInformation(){ return empty; } + @Override + protected long getAdditionalInfo(){ + return ackSequenceNumber; + } + } diff --git a/judt/src/udt/util/ReceiveBuffer.java b/judt/src/udt/util/ReceiveBuffer.java index 5e5061b..51ba476 100644 --- a/judt/src/udt/util/ReceiveBuffer.java +++ b/judt/src/udt/util/ReceiveBuffer.java @@ -1,5 +1,7 @@ package udt.util; +import java.util.HashMap; +import java.util.HashSet; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; @@ -36,7 +38,13 @@ public class ReceiveBuffer { //the size of the buffer private final int size; - + + //cd + private final HashSet hashSeqNo; + private final HashMap hashOffset; + private final int leftNum=5; + private boolean isRWMaster=true; + private boolean islagerRead=false;//大数据读取;也要外部快速读取 public ReceiveBuffer(int size, long initialSequenceNumber){ this.size=size; this.buffer=new AppData[size]; @@ -44,7 +52,8 @@ public ReceiveBuffer(int size, long initialSequenceNumber){ lock=new ReentrantLock(false); notEmpty=lock.newCondition(); highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); - System.out.println("SIZE: "+size); + this.hashSeqNo=new HashSet(size); + this.hashOffset=new HashMap(size); } public boolean offer(AppData data){ @@ -59,8 +68,47 @@ public boolean offer(AppData data){ //else compute insert position int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); int insert=offset% size; - buffer[insert]=data; - numValidChunks.incrementAndGet(); + if(islagerRead) + { + // cd 为大数据读取准备的 + if(isRWMaster&&buffer[insert]==null) + { + //如果是读取为主,则不能覆盖, cd + buffer[insert]=data; + } + else if(!isRWMaster) + { + //可以覆盖,写为主,直接存储 cd + buffer[insert]=data; + } + else + { + //不能覆盖,还没有读取,则返回丢失 cd + //另外一种情况,重复来了以前的数据,hashSeqNo都可能删除了 + // 比较下与当前的数据 + long id= buffer[insert].getSequenceNumber(); + if(id>seq) + { + //已经存储了新的数据,则说明当前是旧数据,直接丢失 + //不再需要该数据了 + return true; + } + return false; + } + + if(hashSeqNo.add(seq)) + { + //没有接受过才增长 cd + numValidChunks.incrementAndGet();//没有解决重复接受的问题 + hashOffset.put(insert, seq); + } + } + else + { + //原代码,小数据接收完全可以 + buffer[insert]=data; + numValidChunks.incrementAndGet(); + } notEmpty.signal(); return true; }finally{ @@ -119,7 +167,36 @@ public AppData poll(){ increment(); highestReadSequenceNumber=thisSeq; } - else return null; + else + { + + if(this.islagerRead) + { + //cd + //如果不为空,则判断是否是覆盖了 cd + // 不正常覆盖的值 + if(highestReadSequenceNumber+1thisSeq+1) + { + //说明重发的数据占用了位置,新的值还没有进去; + //说明已经读取了数据 + if(this.isRWMaster) + { + //写入为主时,数据就直接覆盖了,不需要重空 + buffer[readPosition]=null;//丢掉数据 + } + + } + } + return null; + } } // else{ // System.out.println("empty HEAD at pos="+readPosition); @@ -128,10 +205,17 @@ public AppData poll(){ // Thread.yield(); // }catch(InterruptedException e){}; // } - + if(this.islagerRead) + { + // cd + if(readPosition>this.size-leftNum) + { + clearHash(readPosition); + } + } return r; } - + public int getSize(){ return size; } @@ -139,7 +223,15 @@ public int getSize(){ void increment(){ buffer[readPosition]=null; readPosition++; - if(readPosition==size)readPosition=0; + + if(readPosition==size) + {readPosition=0; + if(this.islagerRead) + { + //cd + clearDeHash(this.size-leftNum); + } + } numValidChunks.decrementAndGet(); } @@ -147,4 +239,52 @@ public boolean isEmpty(){ return numValidChunks.get()==0; } + /** + * 清除重复检验 + * cd + * @param position + */ + private void clearHash(int position) + { + for(int i=0;iposition-1;i--) + { + Long seqNo=hashOffset.remove(i); + hashSeqNo.remove(seqNo); + } + } + + /** + * 设置是读取为主还是写入为主 + * 如果是写入为主,当读取速度慢时,数据覆盖丢失 + * 默认读取为主,还没有读取则不允许覆盖,丢掉数据,等待重复 + * islagerRead=true才有意义 + * @param isRead + */ + public void resetBufMaster(boolean isRead) + { + this.isRWMaster=isRead; + } + + /** + * 设置大数据读取 + * 默认 false + * @param islarge + */ + public void setLargeRead(boolean islarge) + { + this.islagerRead=islarge; + } } diff --git a/recFile.bat b/recFile.bat new file mode 100644 index 0000000..2a30312 --- /dev/null +++ b/recFile.bat @@ -0,0 +1 @@ +java -jar recFile.jar \ No newline at end of file diff --git a/recFile.jar b/recFile.jar new file mode 100644 index 0000000000000000000000000000000000000000..53693f78a935988d488450ee3eb238831815d177 GIT binary patch literal 160970 zcmbTdWpG^Uk}N98VrG`b%*@Qp%*@Pai(1@bX0(`@nVDG@qs3^^^WNv2xpQvZnRziC z(fy~th_zy6WmQ&IEhX76;OHRG(9j^k;WDxy|LKDc0uCZCt|m+`tsucDFRUOfA+D;% zATRMT4gzu~KRF>MOV2QeAWKg(Jvq~$!nDZx^U!5lnvP)^L5gmyR%Leo@K%0uaseVr zoBE(Q<)qF0sOT&dqzR&!B6xMEQ?FAGL`fD38vg*uCh_O0e_dMX&%MBcfIx$Q_?b%o z+r2>i`B%-{)s6A5BmcPF|N98$zmEKMPQ~0*!rIQ9!PL&!)zw|~+yPY?`2#VOp>ols zN=FyMnl@>CO1266Gc6-dDHFO6`^9yYe~*OD>`CY%^BMA^nu2X^5b8RAksD6BYG}*s zD67qnm3QZ2#&9P9#OpgHt{;4SiIcfI#}A;Oz?)Tgd?UaE8zOcPg0&bB*q7TdCMZYW-h`5 zSR~OxVlBZ_>kIfdML8JHpz`Fgbs)1dn|zS>-P-BI5{e;v+93IZr|?LN2~c7>#p`a^NL%HP~H*&+?&* z2a*J`(1aue5k8#~-tQ8x?O(rBDCGhqap_?e;+|AzyPxP|KmU$V8JDwXelQS_x-b8T z(f@YHRxNck1b@cXew~zImly7$yTZNt* z#ttK6{=C}-DnZmz>TyWY7%60>L6O)06dZoevicZu21g^Zm?QYZWHA|11DO*=ILWwa z*XQ=ZZ8bhX)(tX&cnh1`WEQi#VmeBe-|I>Nn%!%##%=)v0A94<_P)1VEw*aB+g*=6PE6xeN7HOV??FXZm_u$;V}3tT=s6$A zb!iku>Nym6bSzC2MsaD9DXa?C;40&3w$gROMx;RvVE@9~I^!H$(m`Rr2l{nByzvS^ zv5bJOv`6(3E9n0+7Qf$1;7#EnsykAYMip|Ge+VbZP4$-Ja*Z2{P4W&ClmDiF8&NN3 zFc+{E?GjNt5`i5i7+E-J#3re_6JPFiqr%WiHzd42Po$J9!RrHo&Yf+igHsj1CB$?*k30$q*35?Wyd_IwXuUI{jVut4s<77LizgX=@ z;6?}J>)&B5ILUdAXzgrcXpGMGSao=K1?Sh~apEMI*U+oo6IT$&1VpMf=+|MoH;d0Q zwGi~hRd}bIvQ71-yuOQ)`qgUD*zXEPn-Irs-A3MmMK`f z-n}dXgOv?uK2$^7FnO33cP!8%tr@?Dw!RhM4XhEAyKcmb1Om>rh+w=>>e8>4EPRLg zWxlGw^j{>gXcblOyuFN^r}k8|29g6EaU_6&HqQz!qyF9pt=e>j{dN6L44{(vzp&YO zXko!{o91eH_XMPs2IMzMT71mC{q2jVnUr6tx|1ZXQZ=Xt2oTsei#0lc$lYY6G*HdJ zEAC6?EWs16B?NI~u>h*|W zmh$ibgpxQ6F||)&hb--nY+*$T>x^~LqpQKn`So0U7x>xo2atO{;Tbvw6Q`XQL8=h& zjJ0Ac?Db7i2YVh)maI=oiGY2GVNO@eM<)l8VYBE7W>~oK`&QJ#R%QazOYZLRWD~zT z{6pnUpt3)tJ28I_u#O`?Lw08SU0l1mAZUZ_M|V*NN`Z`8xoHy3ob(tgHpKxn z=4nw7UpY2u?n0^R`&+!H4Y5f$#7qG@9DbHdo6YJ#DZHKNRl$cu=A&#ezz!40;zgUc`tl_2SJc)BsKP1$iocfKr- zbU)-P`tQ%p&8;f`5X}1=NPm=Ue7pd_stspvW^TFmyl&lPUu_D0c;E1T_g+K~0S7Fb zZ%n+ZinnjfXJ@G+qhN2cG{^W2)LtEFaG}41eAz-4F|)hPTg` zGUDVA&!$$>n>Au9nCkVV^`7S411;HaOH4BfR+2f8>N0LQqEwj!S;5ZgOU`wQ8(UQj z%AuprueQ`qM6b$5yeE?)6`g=kEqE%;TJpawN^m717hvnbOkd}1n<@2M7H-YD?t7Ey zXI$(sa)0}f>r|WjV$3jI)pP)))h(S2gg=x-X?g7xIn*ajfbCoa&A-fI%MK4TePO7? z8jy!NdwX+Z4Z1&0k2fz2kqEm#Zp86ZowWNb7hl5ZX#_^Fz+{99jai*_1f6OnpB?%b zZ6P()(1le8;aAu_6%dxldf+u1Xe_>zH&TjIjKXD?BAI(z{P&F**{2@$HE!!B6$& zvXGJq|0gB$>I6w-bObUhfW!-9X<$fyb6g;lXKP4``2h})OT-@Cpf7i6Qk`{9k`4PF z8Av%w&gkasjJ38{Vdc$}1@|LBH1JwhuOrbHSkpQ>%DJU4=1!sOBPa922{N&hERTe} znFl{kA5JPJpKzbfHK=hK^(AfY7&{lyLymZYTaxm~`t*+N5+A`kko!n^HwR%{ne;b5 z>~kP(z?^1!eCRKXtr^$uVT2TdAsV(#vRvwv05~3Rbmk!QYCt-15Q_$O3vR8-$1pR* zPB;QYx|GR1f-mv&-4B(J8{5DWjLJK~pp9qD9SD^uAs2y9u)oO7Md#v__J`a9|1G)y zt@x^%|3&V9P}^R0Lj_G3nO_u>qjG{CbdR9ViX#pVRGev492o(!ltqp1+FEP4HqNee z3!&$rB1JvIy!;L1TW@aNVh)0OS_q$;Wr=V5Yu3W+-OLjqNY2ly$ghBW|6LzzYuNra zWFTy)@pF>lwOjf|@%{E(852LC+kB$A69e!ag^`5{Z^<;D_7)VrtZ8-NDPP%8deDsxjHl9EWT^Y>OShd0+IS+`rG2t|KW1OFddCabf+& zTPI_=f~X%pIK8+{&BB_YI7V+?1 zpWw+U_u6Fv{TLk@@8(T?quiUKvoaFOp6pjHR}f)E8i^S}ZvhTMV)%IASLSG3{iXvh zwD2+TVB*`)!7H0)dh3qK^kwE?aM2#xPI(3zbrV@;M02K4ZH!Znptmy~mNe2h^4&uY z|F{iY>7KkjYrOB6oIE+k@xom{4>ML@N0}__Mmlhk8u(V?hgc5h={h<|%r4#Q$2Kvf z*{j0)vr(-HyCn?wHXcqBD&~mm3Ge3`p>*$2s3g-|Hh2#6W`+9pkJbB>h*z5g24v`(= zmULkbphlle<1Te$1sAGB0*WJcgO#kzE^NOPzNGVzT#aq6S)1(TMT`ZDeL=$W>daI- z3#UYLC+jip1{RwUFbcfCi(`NVtWblG0ZJ9qF1Sd<+~F&vjA91$DB~sGBT97jsp};I zzAu{)Fj|*D7p(SD7>6q#(b_3*tt6pc_Py3pKptJL`8gQQz-x0pr`O_XQvOF;LQsfh=ixac*tCw{uOBam$EVd%_H$y?$ zhFpr7-!{vLYRieINs-dVim{-DvfMb%FT*WNC1~c1CTtPaL`oUZetG;@oQ`3@zvGDd zR@T=Yfw?nUSY4X8$8+w;wRl7^N@zalJYa!2c_+ z1gYn5QLkPa^nnKo0+RCQ`(KL&{6C`p@5lSs&mWhAB<^HRyGJZ3qKW6GwmO5R@9 zb}3w=sw4%J9L~_M?5g`-eX6kfuyDfsZJL1SZAg35_i4>C*Z=Y3v1Mj==JS1kT)w!2WUA(6{=8Vjx}fPH(F-^GAJA3-><-gkYw(j14B zni|<{COy5J;&(Z0(Q^0u8VemVT)e@vFZ26Wa|ONypd6!vzz)BD=SP>VkS;yIZZCUST!{D} zrl=zg1P5Cp*e-atnxAcT&P0d#HmY{cax8^9W=?9Eu~dCyB4s^!_Q4L9HZTODIU2E0!x0G#MT4F< zv{~x->ds2S01Q*b%xjhTvPMr9j8)pK>@?ZPKHy)!TJRThA1>Xw-6xs0vz)EZCGCm0 zMUS8CGV#n+KmJ;ni%kTN7~52xFon0@5h{aL-cC4AbLvL>tzQwlb3Ta7gR`7J(_t(yEWo3#~p?hVdBIbUI@f zVr$m2CeNP@`ml<8?e{KdMJY8%Nnt+dlP)8pgm{cE{-ngn>?4c;mNKl?l==yWec=$Z zW;y3N(COi(=ABZLVaLyG6ji3IFom6gzOW+w@p^F(;&ulmyD-eOV%hKjeu`a=1Kr%Y z4)y@otoPIny^B}5S<(rwIb2}O7wc%<+PI#b`P*Qm%p+O-rTjmd#j^u{=Rsp*mkrx=@P<7OTHE~BOJOUZ&zV4Gil;$VPDFL zjZe*O>rvLJ4=b@>tixre%iZ*O8?U3@%ZAG36`?`L-QL5u?EqQ#U$#63np^l%B^S|Z z(O&e?c+dF&&J||5ZGRIU>V>nc`J0q_M(JZ|OESve1fp!*&}|0$5J2?dVtSnebGV+3ky!VaFS+9tRl#Vl-QQ7P?6l0&33A1 z#uL4UDf;zVAgYce6@Q=e_nodL_dBYps@#$3b%1x$ipKBbx(*M}ta=z(cL22f!*N1+g@Ji>HNk`!>?Svvxb+BS^=Mz zhIoEa&u96)sOyla*Rw=Zo{T>S!E(Z_35mNyru*tIA^5b*4ren5gw~J^x%rX@7DzC4 z`cI6Co4?m-SuL#=Ig1m8MX=aTxuBeih9(nZ$cTS`ZIe-Mgj>J}tU&9yuB^(5EQl2G zUJ9u6T3T?uA0#i1dOph8!|yKi=ow#$bik_qMV+HH*HhoTa&~t9vedCcaXahx4bh!> zIAH+kXcj$6O~S>?6ft&CM#F6vL*IOikki_sZnB|3@_yIeSp_~~;bLA}W}hyRn$8)N zb5Pt_x>KlYhV}`n^spn?OeT&Yd(r)-C&A%sAHNrRSNM$%Z&0FDA4rvg@&Iqtegk$t zS5CipmPJi&A04~k2=vEb$06ER9;rJlU={z*Psmjqizupecu>bFM|5 zh8EIHLa;){>V}*F`_^(%QTT>?&nzRF%=>dU@)FYHRkO^4auzoXFxn(J1HMVH$Y_dt zl1YACB<0qd>Rrg(*h`n!1pBH^Li)u`1RvVgSWdp`qln%S1Kk^tCL&C`>G1xTo@`; zjpa%1hMA8)_4V-L?R|&v8yHtGC5;Gd29|7_Nu*(6zh1K(v)N&2WNi?C)Np$}JfLKd*CT|3%{2vxtrCiX=;41i6-+zH&L0mg@} zgIaS1a-v^kV+9aRujV+eQjizY$8S=@T@d9PW3hSU*`A1DDc^;BThMBPE$)xAP3t~f zwYJ^9<%gw<-+j)gPoW2s-5;j2wDD*-*R?8x%DbC7mPy9+b(O=*(=kyhe3UZ;&p12LE8k7D>dHps`4d`Pl1HtXM zPR1VB67p+gHnyczPwnkXQ)F(IQE~-t^)8Qd4bQ5yH%%lPKn>o(`ms(jhY=Qcdla}X)3if61}+FrX@D<;@-ML!SvpEhD60#kxwsRi&iE3{>+m`Df{dg@RT;5dR1RH z*1_2`835MM9Q=~x-rRzP4AO~M39>D$_FXHKJf?~det92li{}q zm1@*wT3e${d>dk_ZSpwuQ&ILXL_F16unxs%K0`6tOvjZ!3wm@gfX;V0}EP7J*-)EI!gyU8c?^9Rna%2bdsq0M#YDah!aLUR*Mw z)xeKrwL$OBd4}mPsmsVn+HJ!JxX02`75$<*)g8qFX&&;cqE}t_4``<=3qCrAqI#O+ zt2Hah&PrEwh3bNO!^B-3(H>pwdc!F1p7`|pMIU$y9BOfX6xr?zx|FFxNa>eksQL#~ zq5dc0aKC4Ps$3HGc?*Q6)VOZ^w~XrTWK{-2mt5fDmt3WBo6cPBE+e4KzXa-$XS?Nj z{FF)Q6 zDwD6L+^qoFHHG!YdDqe)TF-BNy*w<5H=Zj_iDthrqScrT`uIPL#^QI~ClpqC-P@r;Nku zm2~QnudkFcSF4tOX%$K2i4oo$fbtRwH}@lR&Yiu&^CM1l*5>G6uwltyj+HE`LViR& zbzzz3lH{8H=keT^W^n{aN0R0{{LZeaOOY)or4;9KSOsiUT%<$sfK!%`_ zmb5K;`=Zj_)4$Rm zy!sV`be^YqO-p&S-|^$Ni9AGZw_I1V$765+wbgvbB8eC2l z7>ycwnW!y)6ZIj>!_IO0tynXD$^-XE`<2nd3hB17l1-ov-ptx;p(M_bgfWc8VRnj| zR`RL7%M)>+x%T!;vLpKFK#{9>P#U;$AShhRXvHwZK^5qHxk+{}r-~!{gGc5zxVyfx zqs*CNNEOVzw@pX<9;dkk`>x>#O&v5sjMz#jB?#s7P>`X4p? zAMqw{>|kv9f82I^WnEb?Vf2sTt=&wNx$SNpS!hoxNo|APRJYSgK z+Wca3qJnvZ7*ld0+6?encT+D6mXG^)zX*B-I1tF7>$_V04IQ4R38K!D77*cJF~0Bw zZWSUmUMO!<8@BjNM!=K7un3;WPjcIPM-$<=Z`Ib)F4}w^A`ZRBPi&op5E`g3o%*u^|rzwSi@1Tg6k+F7TGdbYC87}1#LL4$W3{ct`r5*zJiucP=U9h2!uw4 z7eFv`#*cIcw&fGx#TpO(#>6Z#FW5&;Ll8v7_qe2KATA>qLrb6j#M<3%1&!5Jy>DaBiowT%V#koZ=`HQeI_DPLa64U74RT;iA~Nw zvR2N+mEuDvAf4F?I|5wAE5el-1HW ziInQd*AknGxPtpjc4e_$|8!B6H)Q^JN&L3u)(h&URaH-L z_rkPV)FeTBQB=@XK`l@A^^IlDq?v=CsOUpbg1xb*mZp8@{k092(>dG?ua6(MutspS z902U`_r)IjEXnOAxpk3<>cys#82sQ3EYAWI*d_ZckKgmMcF{~p-Lnm9)N?T815)#F zd+QWsO&{aGRQws0gzION^xtD^J%-|V!~L{D2B^YfI={f}<3qH4 zloVdRhw>iig!JZBGr%4SJZmcjWb3HsrUjIfLzGR&a>8p=y^AAEb&vFS?D9GAXb%LVVXw1~< z{s8%i9(RmkJ@bE&Cl#EnWlCi}t`qVF8ra42k-A!XH46N_!q8-q{%ZdRG@1VmXsrJN zP5&>R@$Y9;oNHvJKfZ$sBne|mfQvJ#AX^DXGV%|$BDObA4F}x!1Qnd*6VAp)UfPKe z@;IgQ9_MgBZKlW0w0MHNuFl3AjUp9X`WK(BwUF33jrsO7s=JfnRDyo{iIF;Ca9GcZ z>`_WO6!$7zLqhF6f&pJvdj(#suTl{^PN4k08n58hue6CTxoX2oW^15n*2`oqBDww@ zV2y^O1;1WGBDX?7%}~$*yw=^(cXgjRa>#rI@*wpU)%Po5FZ@s=r_CUg{vu9ylBT&3 zT`Nb|ZzScqfhnxCZpxHlaImpA8Ik!xd{w$a}8CKQJ z=#|>Xm#Xs2o(dHRU8_)NgN|mDQcO`ID6M2>gq%@)5jPFXJial*G{KnW6V1&E8%2Be z$nKJqoh|x%7=ls6~j_qH-+5QJ`DSv^UCiK4BvZklw!s zsJU69`JD8cUuO9pZMs?t2<&WwF4k3$_9nkgIgdg0Gp_sv8_Ktz?5PvN zze+e!|Ay^T*pZald*%;pPAA}pqAIou6WJ>7lYd~FRw|z)xp2oxK&WA4F-qgiC$$$6 zofd<{4AxK%(OZb$<7q#K>ABlt-?_KD^k};(y#tq{p@kp9@gH}uFL;S(Q|d1VVz5u4 zPYmM11K3*ZQNRyLAq#(rchfUux1JK-2Kpe}dJx;Mz~OUSML3;2$lKBGuMr&ttm6C* zdcv8cr4HS3@#peikN=i#i+||$ zP&lpshi;sI(XFGOQR6S%1PHGqC(K)1)-K_A7n#T6-v6fC1_peh@eE94N0A0$GH=1} zI@0XxkbEUv$<=lXspU?fRIu@S2rvm00SC=m3tmSWg~eSmGU}w6{%zTF#cr#i&3DRQ zGCRyjMca5Z_Efbp0b?q*C=d+OovzecLW?5Bh^eU6K8lFyk{Mf`@z&n?Xi)w$&U4W= zu0_?l!{FzrgJ=kUjj4$~PA=?UbjxA%3j0rV6aLS1D>6pr5nm(D#xO~0$u&+fWV*w4 zwZOpCT>J%E|2N$b+pu%P{y{gDzvwplxzhS$8>xp)MHB&Hg4q?KqLK1+XnB;?#4}Rz z{O{s+p;uY`Khq8SU!KCh>5+fHmaGNirM86eab?zz2fzX&E)^3}TeL$aA{qrpM-7Td ztOXDHxomt(^kqOU3!-to90N;dvx#b`+%VNhS9cAPX|ecH!@f+XN~fv0bXBKix!K|L z+qQ3mIUsyD^Xc+WCUu?pHr;ldGofm@?J4+u%qAZ)Ok}LwOHxx_ceQ6dyy;n_J6S?3 zSk-uxW=F?Reilndo7M4!W`I!D2|{Epjq!jJU8bwe5X`<5p*Q;1UyHPMWk7>34xL!N{%`gncoJ?ZcQ#@gW8d)rJX5`BSSin8LhM zLBDdCj;?2NEPye#c8jfw=ac%cvLDsLK3Zp zJ$Qy5p-l_dr9Xn2Z%g6tz<)=-j1%rca+gP~J^@6Ia;ZqKbZ!QUz$5FUp+~Np2z=W3 ztVh=X9GM7R4~G@p_W9^izrSJt>1KYk7i>v@jR;kW35ovbFYPplr*BTPE;7Z?XlQI= z^X`(jcRf39;%KDCPuxkCCY~Xx6xI@zGTvOdZ38l7Db9%5eyFVXrCB zKhi7OH}Q*VBC;98^&8G$%HF3l)R?>MC%>;bdCGincIcApksI-JYCBM>heVjsZZg_CpM*FkBGZ=!a; zCVvtJ=R9u}e-zGdLn_jFc%Zj+jUSU^AjjC{AjrJ=vRnt<)tE9GJ6+zbZ63nhk&Ra0 zCJVoFwg@kM&+E2HtzEeWleGyE>cH}?a-Z_KObdrCngK?pLClUepk(*b43x#4Gt@+a z4D~8fdi!@wwH6Wn{Ecg%*5;7c;ABiY)!rRmuoF^1@ows1s{15dqc4U6-3FJcBdPN_`72>ll(lsP;m~a zu=AZOn%Nl}O2b`>So78mcVTDUJ(*RNTG{am5+SxE+Xw~X zY#;0)LN3n3*ElH2bk@;RddQ!G49-JkMU1av-}AXE$$IB3Ye4`bN>IxAWZ|jphVP?v zH?*>S&cm3^qH^wr#9%MbS`&|2f@NL-kpf+@Jo9gk_ zfiEcg_Bjg3NxrW)H|O5juke6!w8i$+0V~iR)k!gV)De|eOKkP=;40-f;(A)F8H=J^Cp~p z#5pdusyPzx&2eG>aw1dFbodsUBFDw=MUG&*871D-dKoTtl}}Y24f}ya;`-xNO0SRI znTVUN=en7wP@KQ`oF2NCQ@nf!wj2$=9R|{R;BUIkyuNbih|%&~U2R-wWXvB5BqYdzP{csXsFjrfv?2I|3oCXLtoKwWp5zhg`{UbrWMY0wT)VrY z(D*WIG-t664)38v6uPsk;2LVu*)b1w&b9MM#MCX$z_`1GeyJ~;C(cyd^CMOna<-`~ z0V;;l4b3mXMEbkLtIw(anTH5_E2W&5lXz=P-;RK}K*LYAYOhhJ5zxeXYprL59h4qY zWcGGdQ=HfomDN+b1I@5F2)avYsAOPC+{)4!ErWM{+!G zLoAos47ocqL_qWVq`ilq#tpyM1|vlH^hXxb2c<>$L`O>GOsbG|-TjEfJaxIg-r&W6 z-k~NhEk+Og~C$KJ&4&98a@Ak%$@kcsp z;5y$R#>!drg!wkW(k=UP&^3U6SKsHEt_S+^bzB`dEH#ZkRAbY9sK}@c6TKZ=$E(yf zl~jJ@`hAQaWnV7xZTJV7CvvRQOxb2k#`sq`y>`5&4km7XzVrcWe1#ndMIWx<0afm- zCb))$0l+xF)h2|aIkk?bv4A_nfur+!lC&F?6Ka-TXWG*xOY|C zxcYFcBUa_W24(AvDqV>L3Wb_p6}kq{NoHcu;tl8JeX6s-0_x+7UhTK;)O#@3tv-v@ zVO1Y60s-#BNY^PG8)(6lB0m=jQ<@0^%{H{{uURcg*nY()KabzO^EI0e8Gy6XNq?aw zCNqLW$R22&Bq|z)ABb&0@EjGN(-B87g_Qo{qm4u&>x-PIzI-{%ObvAm>IK!E{dZS<^jaVGiij@`D9fomg}aBslIYi6SAiq7GZZvs=-P^%TZ^DhDuH zp*0g+l41PnA*LY(z>i%&o(=_>XMq*mE=rkDD^6-c`XfIjfLTQjGNHRy2U3f;$*Bst z*}YXrCQ&VC&iHKvf^tephi4>1ftKfz|V zH0s9%@kWl3lx&FNcX7<05>aI~MtT#ezwSKa>J2jz2}f(z1G4kxY6#k#Z{5 zBLs08hDSL%yx}6-mdv<@iLB}kh$Y63!3}ocQ#*H7f#V516i#^^o;9g$?+Tt*9Ii7{ z;;b86LDBVh`1;p;wr6m9pW>MDsnXvd7H()5Gi#hb&Xc@?VLm91ZobAT?1eUefy@U= zzaZH#l3zb*#S$zsZMuC=bWwOiyV~fLyg7$UvR%D;!yjPho1YjElGfkdCxQ@^!U*!c zC^VxD%z0zSuan2W!PW@J5=a{9L4B_2?2)2cLU_9GM+t>FEc)h?)a;gq+p3E|qKiSk zI2*!4l0SaJP8=>vw zPWM*xmy+}s!}6DN%blIdotMs4-ji*w!9s|R(WIs`BHXUd3Rj-MumRziXXK>9;-Kc_ zs30*ohT2z9kM3Ahy6kwGbjq6UEX-BeZDqy)B9u8*Y9vouP}-^y=cuXsISd-9R}DM6 zX=;R*C}k297?gCYCeB_QN4*r5^@HZ_v&kp>!AdfUFXXGbG&Q?E^Dt2Jy1OAgGHz83 zx2S3U>Ze5=ISVO21x#!fX$TL78c=_-wa@o?BQY`l^3?t32QFwV8gcL8*wjW^}WgWX3F+ z{Z|k6*Cy4!^M*w_lxClF8o$FH38lRT3(*FH`a1+)V+)gxGRW zSg;>(*tFA8V%WZh-8Q^mOBdiR3{)Puk+ysjO}iPBw8WQuo2IZ9arB^AYv`Hq?A~F2 z|1;YSfOG;kv?@hi3Bs!fTFCaFG20$P@A!PGc>w9#9Zhl%JMbSg2LV z%ctYdY_KDZicT`e+RYnB(sFku4a+2>CI7$lamgWGD zE@WZg>nq`8srLoPkP1laV+%m@3Rxtg^88>7t%7-HWI0)V;z;m6FQ8zqqT|r!M`MM8 zb4UMR!$(=YE|nNr;G$8IorWNh(=58Uj5>LT_hECptCmFP@lpS#mT65%o2;A*w7kjc z{hcHeMP0>xN+S~Wot&8Xl{s&B&_peYh9DT0E$tyIx*va;IcSbV+?o=@gk0QEtn(Pd zpfaeSMhSweY#&`A70yY^NV2Hjd|rXZyl#?NAfkA;vNy%$0WC+?{@b(+S}o-M!Q0P| zUxMAgDb6i-XL7p{cj2citlNlc+v-zctMQr4ne+Ea49qrg(&5LbF-@x`qNASfsbXb$ z81~Isp0a`xvaz%;MRdQE0Hm9AG$LdqRqEh$9+OmqsjJgX;6nwjgVTniA)_E@4Vk=_ zl5l1mleCA(25AOQ`z_SLYf9rT`mGq?d}3zdogfX>LmK~JTc#R1esixnAFb^d9w z9p-tc=H?7Pb6}=$3-s1oa7xxTm{70}T3K|^!vIRHII9jI1nQe7DsLoKXHIyrXvY`m zmb;#_MlZ>F0l0ZDaVb`!(hgIisv22Z;VTxakxlJ3E8W&U*XHrVQW2T$$@karb@Tbu zV7D82n>mKQiXX&R`O~YeZ&uN=TgQ?p4fk`a0 za<@3-Ne4pRckwV6uXeUtdO|dwQ-c-0W$5+JP z{%lRhb^BmFUj+@2#XOGddU#jy-!S&4`uGqJ=hXeaPV9T#a3zhb`VW2^OpgEz@@Ew; zz|yx zpA@+@{m)h?qS=?v?PuSRXKSAr<*d>^@TT^0tD&sFt<VfFoZ-mFQ!wjJ*I z$IFPn^i{sh|CyEv|F;v`f7>(tx9s>2mnufX`p@1Ab^yahoU>REv6grwy$vRN!D4}M zc@P{I5wcialZO<8G*SAWXIbUJz2(`l9&l1qtJAAGeHs>U%Ka|S&+mVg4Jv}#I5sxf zb>*LWtnc{o@$@7Ja=&W{;SS#ys#1=P7Ar>FHk!>mz&5|BGTS@bZnVj4!aX22Qawq3 zT{JM8L|b&4X57MnB&)!Ih1N*Ne0oba-Rr>Wc8WKTnHwvA6&W|1mNc-#gS~$hLPsm$nRFk4nhIq01|8w>SCfGzreL- zGW4=mtmX&=AVS@%Xs5UF7-Tt`Rx;4e906TkwQ-2|#&)$jL8 zg{~7IA*M_o>LCf$ASiLxZ8g#(12ip!1~{x>p~HL1?bNb7+NNz*12yV!=Vt-gG*#2K zt=|#H!O3@A7!Z{uvgMX7tmt4V(W4#Cx=y2qVv@l0i;67b@9)c7qn&pjFaZ4dRW{OM zmf(p&j*%Hve3q)@3+THKUM1{$5Xl)cN7J=^cMyp}0EZCE4CicN*`rot@>Y9GxDunD z{9W}<3O=2Rsz)6NV)dTt-IVKYWgkWty;GW{H;(eE_=ltLWvP1&fk==aAz_l(&6N10 zZBnP#G$WQpDhw@jIpbduXQ)Q!rK^CNb>W>sSymNOCb)9wdV>tcW?CF)rIGLsaAb>w z{)f9xVb*^4r)Vl-6MX~_>;=A+j6p-h*%U4;SnsdF;(PONPWt=c;_vuD1 zw_@@2?X&fWDB={t+Y~6(C%lPhfKzG}zlS3i2M{pJJB-PG-&mC-P*IF1!V{A-(rJn~ zmArB_c^u=H=h$0UIOl1c&9PYhy{#yiVOD@XxLMK?TNHdk1k}H+fk+IUUw_6dRG!9?xtiaK8aDmsnZeNL1r5VY!c-lG+{qlkoUFipC50JJe|QQ3TsV9> zLJ5RY>WXYFmjryl9J7Nzs_MQA$T_Nl4SB>Dg@z7~GW#eA{TZ5~&ScCg4NBfG%2S$Z zp<|}ts3PE~3^*$CnZihN0MWZ;5kxtTe{B4e1`|;-6u01z8O0*$$#;YpV)hv!--Wp_ z-|UijWer{0NL*N<$Dd6k@NF?lnzBLn1#&GF)pvYv{oo_Ar^m#M{%VpLKxi{ z6H{NS8GP;6x?yZPQ1O~N|Be(mbImP&0yl$^dP}YxLOW&j`Li-e&X%>ieWi&=ReCeEpY#xu>Ft8xv-Oyowcd4o3*2ZsH53Gmuq4) zwVhN~a6W+USlZp#(vKL}b|TuS8$$33G@Kl9MtG&+wTY|FCV9P0Zua2yMWdQ@(~#E9 z9F5jG^}>1D=Sg%3MHtpnto|1V#0v@rzZbjNvhRx*TI5*KHm~qu){qm+*j;BHuRfnX zkDn7|2?OANTKL%&$m9ilBTl#7NSY{Cg&C1GXXRfjvK2vtzVt-ovA3pVU0xQf-;wtM zJCZVXBVj*<4NvRs%(1iRcV*d*OJryj=!AzpLE~PLPcVx5{>`5xd%UPK2CVxig&0&G zwuWNK4{izCDf$PCgQ2nC;1m)MsWmL(NCONd|G|N(i~cs-GA%Rcvyvk*d{jZFe;G`m zlpn)u$7q5ZT9)&CX9MqYeGIM{$u5Z-dS7Ol~gK;0~2hE>tlWLk@2 zsDCC>TF$Z$WnY}ogC{pm zl^t<1lv|yIEwE~et?5N` z7q6HmaojF0+%za!tf`BRcF9%ex18#PAI`@#-l=c&A}g-r778w zq^5$wV!(&k4`us_;hv-%-wc}FuzQ(2GFFL|I3@Y$FB0aMU0rCi<4?EkjgcNv%lH&! zurDthA|RN8iXsN-sOvta!q6NP3bul1D~toG$yTNDu_t+9mRGS=D8j!}45?kKoHmPb zBvKvRISkw4$;EVdHWblajDVV0`ONSu&$PaLT1C zYdk-);@cm*@G$BRqO`BTm3?-OllgerMEh*jdV4#y{BXZdBMj44srZtXG`;oz@%0XD zg0@?-W~FW0wr$(CZL=zE+qP{Rm9}l$Ir;70-Dmc>X8K3G>wQ+NJ0j?6jY%8pB9D*m zgEEgvseC2<;56OA;gC#ad9Sf0YIlG&%?5H8irWpHtcMC^eArEQ5k6u$;>9mjKKVsF zLU?t)m~ICTbCayf>CSD&P#Kw;XGRoM_M6mHNoL2Y1$S!odlaq!SvX8bb{#f~z_&}S z^elRE*A z^_y>Cw@5f)50!9*Ovbf@$G9S%sWTILm&E3S!hA@#dbHCi^&9l}u>LZRL{#Jaq57j3 z4UjMvt&l{cW9!srvX|f6Zv|nJgEfkJ2hrjTx2WgBvPJ%SgR|Awi6$QuG-F_IQl6B< zr#qRMk-6BrH^yD9>X`W3^Y42pPlikxclOuVzV2v%btWR6W{SQKYK_Oab=Z79QH?vDanjX6;P%J!eE5$|E%FHwc z!nxU+*5g%TKuwhg?mUl`yRFF`bKymlh?m@Yh2GX9h9-xa;}*gR;p2$fYRwmDjT1Yq zwi5QcpK`nn1`_n62K({3IYP=>{V}$_2Y64bZ#%W7RsjQ^^E@T`Qwcy4;HpZbD z@=~)1kb2Tgf@d0}(@PGEh4C}v$}~iJG|BfZk;S6o9sW#F1~}WdZ0l7Pk*ra>EdL-vgV9iFT^I>nf1GL1ol!R98uD@!i3_cNFQSMz4Ug^x|qTB|Q@&@snl@cfi z8lBVirS=zv8l1;)-~{U+_0KLloO?tr5$OmApYid3)j#x8pN71IsiUl-q={K?R{Nl^ zt#EchFq?M=|1$anz*S#_C*M2aiCGE_MX~3sq`-a<5o*STku#WtU2m!xuv?ZDXc?I0 z?5G~J2_g2{gyw=ckDsl@sXu=b6+$tHdtD@((zggqcrTaB6fWHJW3KGZ)5S#P%J<}fV}AJUB&i8~JZ_~GX0c9lLr5)50=k>1-%JZZm%wa~pO zRBzjq0$?`Q#icifsqGAJoskfD2Kng_8q%iIXw;*ss0+|-`!8ET92{+qE%<9b*mielH18-7U!WyElI)^-h=QhHjbGtlcccn$QC6;E z5qNp|p$|lUAsOOA=7(KJ9kLUzy^M$Mg|6_+dA^RXgo6#ba+AC6m!c0a#2snv@ZMn$ zD(yjhDDS=_HG>-d@#R2` z{tJqxwEQcjsN4*g`3>@bcJFX^>81khMzf?Ea_dIq?-}fOIcPzso`}r4G73i2i%kN` zsoe|~bdC+`t(BG+f;Q@HM(FR;Fs1q5y5;cPpCuHv%EiUs=2m0~s=$c%02*{t9Hx~R zK*DPt`Qt;phUI}rG?d%ZOjmR_Tb^+|r^GdZDJ!e83Hv65&nSkUDuh4KRF6PrHlgUW z;`n;vJ*>kEZM`?7I7NrM%^ceYYL8NicyuX6`8iDqqh68evAv%{ZRio)jh87!!$Zif`fC3*Hyl zKjLFoc<`|H&uV=F_y2yQ8OHx-9@Rhg@PFAjg$y(a&uv%XOS5=_ryKAVp$Tx&9>ZJcL2x6e`cBW-&zkH$zThy+xz9ZAeEq!Eiw2n7vjwFH>f5Z|rls?$Q;Xr+6wUN2 zv-e!~x=6~cV0+42qnN*Mz4iEf@6cc;6A2QJ`;bri3h;G4oEk{k+=pbfa@{ zc4n_t&W8#A24B;T!Gmt&I|hgs(ZVeh}KNgn_cSomw5umFrx# z&XhC+!E)WpYGL@J4ay;_2vzXsZ%e=wk6i}_IrO3?OikOai=f9f$ln)()*Acbr=Gs! zRc^#H)qR5*_rfyoG!X<_(CGf!WMW9I!*MnT`Pu#T)M03Zo-=owAa93?y#-wbRyuML zEE5XWHJxw+=5}PehonViMrHKU5#9aS^yRDBX3W36`)nA~&q2&Yb8<|bmiw4Tsp}AX znpA7E8)_s@o5O(QZs}>3$mhZ;hr;(8rTc*6!%@jKyBF)UWT zIYk>PSZEAGaXvDAJ1qF3=&yat-Vx7h5MhD28qUVYtDY6>7QjEcCBuv2O+0jrL_TI` zjD@CcW_G-f)p`uIjYxBKRh5k-tE^R>A$*BP_U^jTuu`Mal@fH@Fj8du8N~45!~_Fv z4bs(1jeFK^4)YX9w%v*D0Dah++y*v6NSHgUP--vv2#-|sPT8!+H)(EH3-fUz_}u=D zf5IsB^M(*B&)~}KbLm|4J;o<&MD>c9PyaqV65sx1dfg2Wq@qUa2Nw0dKId)B&D2o~ zg^D=+*XsZ`J#46z`7p^DKxPSM0yzilVhVbWSLRzP2>bOpSNyeRY_ABY1QxG$&D7e+%$Zj z7-pR~imCa${TSTAz{P;qjzWKu9#Z}z>A~^;in;qI#^rw;+5e@K{r3UEM_Ee_>7U>@ z8x76oW^LrS3iU$d!u(Ktv>`?5CJ-SgICJ8Or$E|9vy3iupJ%z33!rKAs$noBJsI!2 zYjlUH=DP4;nW?8qw(Uu8riRnyoE%=D)IJ~(8fY9a+q(3`n$9vjM>5u`-f4KAnQW`E zdeWx^EH5x^H{?b}XVzI6HE^4nNes=bc!QB@rSgk1ZKwln=D=NQCg+jw+h{wc7bVj; zus(Rzyj&V!JVHwUP{xNN6v=g>ZBHyiC9;l2Pp(-osx*bVu`?M zM-gzI6BYY7#_ask)X9l0B8zy;@#gI%Fz3aLiRaa z9<<>b`E`RCeYnDXYV_s!Phz#l@(w6Qz?iO^vTEg1Qg-lMieIhaf!LATu9KGV38{+q zQ3kzQ;pgawg|?8JP1LlR#(kwXG?-oC#HA!GDPyKgug;c6J}lGpi9Af^1b^O?pcT?E zP+I6G;A)*; zN{mre3X5X@08{Y)1@Eg;)@ZP?onI1%&-$g#OxYuB*&QScPawE{$|}|@EEpE{ERTd| zf3>pjEIxTZdLnjGm?7yF=9;%YFio^JdKXpxa>910CEXeDhJa>yQe$wy(mz*C;2Rj$ zl6o@i48x|!u*86R8G$NgC)@q~)N)K})#~GXcbFRgWP}?*Jar6_CX%{^MQoN3h&&TP zV|byDEC)ZLw9(77cdZy0Omd>$XH=Pg5QbX~Wff{G5UwtzYyja)y-!Q<+`06@ck;Wy zO|36e5P=H!nYT`$6L-A%sA;MbVdnl{P~)0WL*w8N_-+3mCX4_3L-?P6+W$GI{aY(m z`!Ax=&NMzn8dn0`00KS`9zX3DfUyD~IRJG)0=z_MaBG(|E<1f%7?U0UMe$OR>bar~ z%|iQ3P`SRqB>&KyW{aHGrD?@x)uLwAVznww`qy!HiUGJj)lt{`70>g=cjkSL(=_*I zpHRrJNfk1zQ6=)t)T>jgSTQZa`Y~7N7nE^U&5WwxRFv(R+IFu390%mctB1GdlcHvS zNDAb_M*5bJc^=t;wZqG+D^W;Mr3u5ZMDXf;wejfZz)SWXRSM+xb-@Xga3aD5Uxm45 zPvr3dFzEZ*?QGg zD$NQa0@acMNx|Kv%v)AOK1I;(F2U7)-B%*7ekwo0jZO67&AOUai!5xqbv`%%h75y2 zF8v>iQYQHc9I-aVLDJdzi2U2qhCq7DkktiVc}vjcs6sD3GG;^nVRX>5xjwTkdog+_Vw1+5>Pf1`@I~ z0I}mG4_0aAT`9MbEkt}cKl zsmEoSt+?Frj99dq(C!z`fsgQLXGYzuJdP(-+`INJR*$d77M&7hWzq6UzwH0>msHiT zIFgp34ke|%P8;F+RBA@Z*)SQpD$_biqJG!tCD1R1sVtZ}?S+_jpFu)!%i0WsCEs*#_{+5@~s7o|c`oQ|3LsZD$RPjN%iclF?oVRohkK!Fy>C zrgfGp4n?~0AiK1rbl-ILwk>mE5en4SWFz>lhyo|dp$=XTKi>$VjsB0;jR=HiNn~@z z3!<&rmzIx@ayh+jrW0URRQ*0IlG`3Fss`CEEo58trr;{hOSxao0X<)%=MV`($MkI4 z8;gOUMNS5Ep@7$1xHym0s)Q#Q3wmXJUYucAi&F!=7{xLq30`soeu7Dpj*JVz*!?Cc zsbM_(M+WJWKHWJe4sQ5!Q5Ux|y361>$33$l-Wv?}=mxLrqA=()1JXvv&~|~`-*Zbs z!Qt81)1uwlLP;I9gq@e>FfWIk#NO-F7g|_F^8n*SBa~e)_sQM@NR_qfMx-bfVZ>W; z&a}pTSs|~+W!(utn>`2aJbl)X{$2U?aFYtH%bBLSN5*cqizF6YO zRo9$cEfS5dO5pPlNTg_BMr5}OW5&(n6&?*VFm;mO)_Y_x6dG0}2}?`j`F0h8^ex`4 zDIP{A>`DY2R=mEZd&lnCPg*=}vwJeSv5iWn=u9=@AIpu4bspa`(7)L!LAOSR`+5Q1 zL_=7|z1v$!2rNFikm$y%=!dmJH5salF5L$^{zx#=LECCS>P%@75qIdZ-a_gUD)Gd@ zNK`C$tpy29TqYt#X+;;GvBwC_(XPmr6PPJ1rz}ffN#}3vbd?N*A7#F$A2l38#m2NBM39cv`PNHP^qC>KIYa+lN6qb?Uhmk*-UFC}b~aN_#GZd%I1 zlPJ(ObEzpPIonfv%i)=ft;)*A7wjeQ5%L9)!7U)jS^5Wm2d;F}mH~Auw`;j&2}Q>d zqOvFlt#?=LJ|3*>k%3A_F)g}7)H4g{#*RX=^eK}`tR_*32_I(v-P}qSKf7EkPN()x z8YgrbZ0oZM^5E*II!$lTSYBXOS{$#^?I(JWY#1^PS(S&EshTDEd*HnyXG=J!o>qGV6g)F z^l63<&HhL3ZYcl#H-$E}Ym5;y{%P60)kXB_S#mW9+%3z(&xktp@zd!d3(NMunDYC%F;Ilq=!c(3k5#Y zF(X;~m&SVENf_M0kEu`gBD|7texq7l;mrm#v)aUXG3)e#Ph}`R9)w(xq6a|`xT=F5 zh{RMu^9J^GF?J{jbCTlY72NSP+27mmSY>= z!Gv?jxA&%FQ2fVV5fBH=jHVPAbAfg0qUr<-H)4H&)_anXH+$*> zqRlX{O9oQW5IWfq(X2CiDA3>^Obth!B5)BS)NHU8&rKrS34LM%k8=6~KA;6pU6`^|1XnkaPD0)oN{5cY zmynpQB&QxI0Uj&^o-mp#3C(+)jr*QoU#$RWd!jZg!dceIW-H{u-{&h5mzT_kSO%7pZ4-;*z3cu!#8bgp)leQ-0z{<~n|2EFZ#ef1T2 zy{=@oFS;6QTAwI;nN~C3N_)~t0ryyMhL(~jkKLf7d!HH&J+33@_826 zO|Tu`7cB=#;zvrf0tk`;qgKAQWcS}=F5z!nH8`hFAJs5`1Hu|Vp$Rd z*kakHjRlON<4&sEp--5KRdp-kyt@k(ArCUeym}<)PnU&HbV;J%FEDlp@V%8{z`^vN`0P30rbEI$^e0pS{3dbzV6%nZ4rluII5qxa7iF40jI#QBrZGW`?K{{K(&Vf@Dy{_pVY|K7u+lr5Cz<&k-65`&j= zlSDQYD(6s}_E;&agYt)v0|imEh2BK{S;{n!f5+wEpedU^6fk{3^}G^cKW;V3*Pf-y z>LxgCcTBV$A5Fx-;Q?e0cKXNiALr{;o4Qj-R&ZOY8XL+BsN;8+@+~r_}Pr{ttgTB-PGzND}Xmv$j_h( zK{c0#64K7ZAHZla&&Th7?R%U`FB`g=H|MEIwj14f;XpeP0&e~_KnzF}kJ#5zc+d~= zzdV?y^GZvLJEgD?zb|uEz8IwSy9~C`P_DMnYAY%~<;G*sdD2CNcVf5@sPXRt)XESn zT?zRFv}rdGUzUM}eE6=@tr9Spb&@{cjr9jgoNBLvEgHy!EoTq>3ZCBoy-$xPgr_L2 zk*+R&q(lM=%Vb~Zdi0$7NP~eg!e7?ho_*yGu;~<;BQHTvQtF1?CK)_sY^kHa?oQm5 zrwXh#(SknZU(Vhlz%maNy)Z#JwGa4SBd&3{G0c90tF7pOp@vzM1&{s)rqgYv%D8|r z;D&ACk+u=f>^<$8N;Myg?5&>L(srqI7e=QO(=?uF8fPRc3ep}gb66;uVGm;jc?THw z9ag@_$qXO@N`G2o#xq-SFW`$333aide>XY8*fO{gKVwL~14_m!@uqbhz}}cs#X)h` zTD`g?tCX_A&sZpV$%b8*Pt%U@jI5Gf!2Dpu)8ECZUxa~dj`_dPxm0} z8$wbT?r_zF+;8tIn*IAPdKpQ1LCQ8twvj=OjO7ZlmZ%cNQ4ye(EIA$w6HV#lM086K zA&oJ}L}YhhnK?Paz?{>eq~<9kyLHup8-8R}kl3A! zWt^|DPk6}PMtjN@pr@-H+RqRR+Ur>b`B?c_dOZz67vbOk@*Nx5=nvWdh-d7e|J!Fv z^8fkSDw;UB{8Pfc_H+CUhP!P zs{?Nu_&LzOx^y$U@nYyFppH?{p#3pAZE4C|E9eft{E35FWft zey1QEVPFBLV3~aslyIyRRj;B5=2ZvZla72v6NwjMY`Dp{l|g8TS@|77G{IlgZ>^3& zg#oJJ6b>Rl=8B#v*;Ld+)CVCp0f&GkyJ8Qy^zM=xrU`o{iRtVY!WAkjG88gh< z&_XjpQ*_Rn%@dkRs3njKb9r0`N?AEK9=Ku|zl-1w7eV5>V_riEKu;D2#!hP~bmXBC z?z*68f|+Sp{RE;Y>of1lnGxZx00d1^9u-O&b3!1n3g!|rc~qZbNO@>Tol;&RagAbz zp2Z@**CLP{t07$}{a~CqM%_B;m_}*V@6b5~S|fph%j}>}R<0JXf*q6~#?mYEthowE#466cWS8)SHZ<%B5(nFXXR0P5Pj0hd&IK)?QYc zTb;mBcR|@KJrZP|vQ8R*DyJ`$wKb$1Fh~f8C{0A2z8Mgf6o@zApzaxHbmm&;bVzd6 zA4y$Z^N$SNzzlM>fQ|NRgv-#77d%`Ezl3Z~Qg8Ou8lFR<s%X&50=0Zcf} zazIe172~I&q#&Vqai*XRvfqf99&K!|f+u@;w$(lv$l}%yM7`6M7Ux+)Os80Vs%WiH z4^p#Kt%1uaz%m{G_1+l{)GC%sm@ZS|GVi!&<(%ePD*Odi*_+mHpe8=sq&S+Q@~|Fi znn_8AcBSON*GqFTcO-8N|A^Iq7 z`lbPB7Dz;tHOpzbYB#{9?2WXYpJQB>PbsS};ymBnAhdRegR(uORB0*|UuH99N}-^? z=7rNYemU^0Q6cq*F-p1y7fNE^WH!l369SUIgryNZJgQc;bbG$&7qY1K@HHi8Y8)DZ^TJIlUMHo9z=?BQn@+S zkhhax432`QT&Od2o6@~3HM1EN%`WPUBF&M~myBv9FfpN~^2KUp&3)~9l~PKSFoG6$ z?P$c|L*Zy-VshNx;)Jwi)OL%q1Vv<+p`!MWl@XSmj*gIusdAL5zx^OQjXz%;>TVd8Wq5ybV`p{la$Q3XPTnJtM69!Odu9EXdZ}9Ce^=M}^1S0|}f( z3G3Su!I0GL{t+Y=>y+ISa={LYNGM`$2z{QK8d<|>>6NhQ7^6rb=bYA`-nBqru z4`4jATg`4>238EM8UogUC#-4ao<7raN3uqmpeC^U9z}+Aj4Mg@Wnk58R$-I{({Pjv z5yk4fJ{2x>@RULA&wtt4-J-N?5*)reu86(*O~c~Ek8D2O_4VJOMNsJ>(j3OyUkm*8^MT3$H09ReYcqdmS~=PT{Jh0~cmxxb!>@{;XiYinQv z<12r@-Bbq3CplixT(7$5MlxMPiTh$SBII;d?)Vb6@NU*AAqeBEpw?8z|8W@0@Cn`w z4A~8l%m<=Z%N?Qz1|*j)Of}qVHyrBc`*khSgU1!Ve{Ke|11E>;uf-f@w3mvbHK8-F z4x-j7_%v@bay*ZH=EqEG#MING58C{bciPLX9rfA@T7?~jT31Ki_ozOVXAEL{;O>dE zv}>vztu-@HozaWyczO7zAtO=CfzH-QtShVjy0@VfiB6wScR(lKAE{S*gC^acf70k% zZ+OZVW3vh1Q*fXwAMQB}_zLYO7PvK9#tRJ>8SFOJ9XBRCWhGEgRJJo3;1+ayTXgDB zU<;++sQQ$B4|2cM3Ky$lvMgYd(Nv0{1alDoD^M*}imCN{`UQ%KmU`5DE|X-KE9XBWAOAS_&H-H<1>G0`B639jg`$291~JKjB+oK7 zC`_2Zj!w0g#CXvWq9qqK$kRnQ@uvpopEYZH;^6cd~OIAqj9NJ#)_R8qh{<%aK^Zi%#*4^X^AZEPqwM;#LedHzZEv zs_eA<-oG>ov zVxkDUqb|b4zjOvVNAtR@F!LH0_4ElXn|QCLLl2@%7T3k_|BhcVNpit;IRqR0}cM>bJ_ zSXjI<8nGP&t9h1;^H|wD-W&SO)tr>L+unuYpYs(&0*o2C5Pz~kO}8W{BvT{Z{D9&$ zjxkgn1&0gtb<9c0VlJS+X!aBBc|P^mHH3&aTTM7AHH)*nN}0GQpX&CC>)KtIOrtJY zpm*63+2Gz+eO%$I*zu>+eOh@ZoLoy4zjK3Oof$(7cAKM5iYZpWtV-T{3)|w7IdP{F zA+dJoapn6kH)=}_O-iyajC(9kMB$*CJ8Z7I6GGrzu$5{p9MI;IqXe);av%|lOiT-R z1>i|y;g5b=a%B9T@Imbbha5njsl%&w2{H@EQnQt7`J6-i8e7b21q~DjHA%H+<1sN2 zSqByjO3{_&U8P817)G1r)IB2^f>8(V^WbB1i7@xjN!*&z=Q$w%8qlqp!$Z{44kIH^ zX4{lpDQ*iYnxdJ-y$Q{hE-VUM!>*X}W;goZ&G19HnF6IINaDy^u?I9fl&?4Q5>ROh zus7_?v+)}_11KmbFL7{}?;%9@dyv%ZGH_3kI;=FlJFBG-z&0vBCL|Nom_Z()R{LW| zFx8V+xTxO-`?IuAC|ll&kE0Q!M?x0|pP2sXIyT~9h)+dZnZs3Mlb!9wTBe+0vfi|6 zAEyzJeP3p|81`xC=R|$42ceszear?KrhJ69uz6Py zjN-_;H&T&S17@A_<&yi114q6?EP?!d{TghodDgPDRSQOeQps=G4}z}wnZbR zTtdCnilR1On9jYx8^*W;9Pvm(9cSCxKohi44X}bMqj*yMt(7?sDy?mY|2x_2R@*Bg z>|qF*gE8V~h$ZQ*z25B%n+Hr=w`b2BJo!YI?COn5X8H4S;^CX*M*{kFLF3>zg{0KS z0(2sX_XpLjp2!(fsYx4*-&uVxG3i_3VNk}l?gOPD=sKYoR<{^{FF%K`aW?0pX?RP)^*Ae*#n8e39i3ffbcy@0BF5SL6q#V;MAi6u~ zG~=VA;~RE%$#xWbD4Kn?u=4DcNc>Jo4Qr>c#xJ^gPZn=B3Plxc6$ja&Kae^@RFHi9 zSvB-=fxk!lD}>*U0cm(ezy9UNrR`}1 zL;aBfi2oyJInn1o>mvWhw(t)=Am(W2@^4e_e=!6uDppEZD(Jpbh%3xIL5?;cz?xPW zGs)&v>Qb6CGs*gp>f|))bW-&)Xo9R)wy~;JEtXx)TUow{W}E>`S#?c|LvgdSbiOwQ z`*yYaboRp-bk`hMh={*}4>F(cxUW5?ymWm(pWpESE{4P?k%QaEtO=1&@x*ADGB8;8 zmD&sXM`|4uGiLiKXtJQ;WTnp>Li$n|t>4OHB-EA|6nBM^i?Sl(+9C`#YvZJ?WS8bJ znrl#z!c354Uxcqi#pYdN<0%zQ8OyYwqb3*w|KjhZJ}4yeAE|R(E(U6N(cuH{%hsnWIe3o z%nTTQ2zd!!Eeu(u^TA2a>`*E6XFL+a!Uvy=Cr^uLO*s6lJS@$DhNWC1c;z?}1;JzK z*Z9ovEMT=EmCz++IA|@1jsLE0w4-t??UcrVsd;FXYt3GCqj3K^yj$%7uV4Y79oY!& z1!*2dBCXe}MVIIaWRy~rD{N6Y@F0>^Si#RF;Rz}njGbjCKsXMW;jz!$oFptf1f3Q6 z5OgLigyShdoRWeieaaZ89Y80emI(v>8(Xj8JGPfuTsuz2-!5;%3-E8xk zgLAYKA?%p_)?=PbSz~D;nYo3d-H=gs;>bWge+3jW@i#=Y5s6H~S!$oP%-MUECD3;@ zih87dY`L9AF%RvS^WjMIYrwekRK7DWxMF>~#4tGcHq6{b3Ho87H3H5+pze z4>)n8T@sM3RTDI7oPORh29ls@a}6yu0kw{@hb|YhDCD4b1H~@4Bed^M&&!zUqbu)^ zqUFSQAn{#|TgS?HP+iaJ0z&_Xal>FujS1t>>^u$dCQ!AM(bPkBvZL^A2A+~s{As67 z{7`Svw@8d$kj~1zqM~EV)ZLSv-PP7?2V<~K!f4f`JZ(z>8eSGd3kMzUuw{1IJ(s*f z2i+7K1QHl%MU!N|*>nu(Z~>Ki-?#aDqt;YE-C{E2id4(oZzRaiIsLpWN;hBTa0StGN6i{AvT4w@%Y3`r0jt!A@oRZE ztSG&SNYl5<*e%Qr8k$@kDc*(*_dqwJcR9}yj_VV74O(j-hW8~$`k^Av>4L<=IBW<$8<*_$mtALC6q4X~j< zL-;at5ZL}QZ+gOTym_Y{I6kd@EhcJM?*C%R{*Wbul z=GGc$ulG6+evuzHzyEoohd_!l0Q|s+#Q&>x7wf+@)&GJKh3ssd9qp{0{`(k`q_W-#lBxM zISM8w8nB2lBIkYc`v%Ved+**>Q_|d?nW^Lb>b_(8FW&R-SD0R1@3K5W{msanDbbM2 z1(VaqwdCU!jFuuTA@N+_;Z{pwreGEn9ySglrR-o!zhD#R(H3eWMk0{%E{k~^kMy&6 zlZT<2TlA|}Pg z^&d7v)O6Bb`mq~4IFSkPd;-Jrw3sO=+Rj3qu9h`)=y_85A#fkvNn-wy&|FXl7^_ZV z04dz02oWcvP9%3&yr>W>(C30dfg}Z{(3thV^lz$(zNX(fymrb^lzLSTfpQEBO+(8#@+XhxYZLw&F;7pa5A znFggRu$%}|6u16>Mbl1u?nb_2keOR4-so);Q4MxEAIr<-LJ88cxRA}%*t=}^*CVin za?5=5rCG#lq&^?)DLeEMt@IP2CiJSD*X(R}93irj3s?R=c{EK*iPp}`H>KPRBpK5I zOH~4VXNjIcef5GF0SwMH>1b@Ie*L$>rtO_A{ula16!ZF*UIrIF@V ztyv*$47;dgxn;~5`atU+R-4uU0Rs*Xr15|VPEx?|(_yoQt;~MfQ+HgtSTjjb0n+h@ zKW7&y&giMevC)}LHI9OA$xykO7ruoq;)gaWlteIM8d-A;FbP@5>B}ZN`htC@^o%>| z(~#D*S_KGBs?m-Rr?qh?Ghm2g#)j-$UbeM%>iSl%y6TAGDtRwbV&=h|-r7Y|oM<~5xwIx;w-Tr?M^_Ze*%fKSQ8Ev4fS>Bm__vihR1J3 zgJwHtqqL(&0d&JYiqP!wRw*NO+*75~ZVd$+zsJn{7InhaLaP45>)3xMLRsAp&fHgu?OQ_JVq+ zj5(7n@;8%*cVPyfuMeyu!VmOK>0m5v2J|OS|w!{51az%a#iO*D*OwiudiN9_UW_ zW@URiGz@!J@&=5Zo;RGj@3YKa?sK-kf7t`bu`ED1Q@^ho5~_?=rf#|SJ!J}REy5$1 zYb9GT#-+H@GBng$n{xY+PPp<|m`VFp8^d%M`2E;kQ-BS}de@#Sy$O|SnYw>Ks1)=X z>>7p3V(Phk4wFOc(^uG^6u(((;@5EPdi~?z3G0RZa;2LH6U~7F$n3!J8o=ANn-m-| z-tPF4c$4F+mtwm)Tl1QBA_=~8k|R>nicHpM_2$DU$c2$T3sRHLSQeKBB1?TfO%`X! z%r&h-PEL56VEz~Y7#U1Y5ZUXvv}hpqLhf!6$huQ^&0TEP89<@qvh7}lM##q6;%K&x zgH%SUne;~M`{bT>ea;3)g6VwWgrLaDk|LwBXL6*&h=jZ~7l&)1vpaL+PX>|w9#`>Ri7#GRV-E9kF>=4D#( zYimxB8H=%&bWeNib_i)9%oln{)Krkv3QD*`!l3FxprI=^n1S0AI96~-DmLPox=zQ1 z9|reWfD|RZNBMy;Rpttelkbd8gPLHJR;e3SFJYsGU0o9LnS!h^tLN-TlKd>R(PktF zhuCRQd=s&olg8@}a3nV7?3MJtr?7yST4g9M$)uMX*aHBD^WY1}lhD`{TqJ5cQWs+l z8|~y7=tG=2SWMFAk@}Femv14iEK*BGvKp**ls3#%mW;R9%uw6n443yij)?hh_^C6d+YeTUeB6uC>7JD}n$b!r;(7}Lgod-Od zuP96SvxW$esI`S;9S}~cyE<0TlCU8g)lizfYl7EVcKXx?$kkTFv+B|tmu}Suh-AMi zIxNznl_&&$JSxGlZ(-iJq_bPi=utdGC z`5@QzkJ-7tp(>APmz6-a$5NG&F1Sth5avGY8w;jKs$c|g=J+pIfWjeF4 zBNJoMBeUstyZR7$S1ymqtISRyZV5z%ViNpdXI`0x zbq%*sfde`|poU+%5e}q1R`Cw50US`xo6vKqI;i}D&56*-NCH2?2t_OtrOBjP75cL# zfO_&fzS+FB`_1U^LkPR#QrKHTB+SzCMxSix3MTI)28zs3jzctHb9)g{Ft&t14;X=C z&VNVwRe~9VrkZ;~3#pWtRL06dO%cVY#H*CGgdswRJ4Jm*MIb~e(SpCz7j}=@p{ONB zzDe5a>RS>?uv!@sm8Qw|KE|pt+rRRV@YUwanSVD@p3laH3slwIuv8_ji-uxhF0H5E zz;wg-WFNHj+sbRKlp;4Xz`NR%q?2yXuAYlz z{fG4tpo(A#vzC<^*^(0BrfHSBHuhrpFD>jo`+m>v_YNE{5E1PBcIK^}wb+M+^7w2Pbwji9Tl5B%5n|TKvb})*#RUejL9Sk~r-&G!gd!YkCMglxx^q^UrD+r8`Q%-( z>iuaFarI7maD^f%W9hkj+J~(E@jw&H`mzHKTj*<%9V;-jN5RUljb?tKOQb<20=g`# z%A%ue_Qrw(6b5QA83>y^SP-%902Zb$+6e~*XjXp~@no|G)MXG0qSW6aIVjPk_vq*j z_XzVqlLEz|dB<$o9`m_g!iVg5Ekun@nhr4lVa1?__`sf;eVqe{ZE%R+EifNxfRYy) zI4Sg$YH-e-F(Dx$oYq3bNxFZ@7(()c#mG$S8|R@f+M_+Vk5bdR?XJ{yjY96s2a0Bf z3lSM=OZOpo^#^!XsU!<@id2a^N;r8FA)_@})*nm|#yNT8S)yNEH`j}8iByK#jZ{>N z5vwVRniPO_GRyy@7Gz*8wNb(sm5tNbUj_M<0F{NIpp;`Q6-xSZiY)6umKsE-rX#>m zF&4?-XqCpv3{>2j(JvO?0FK3@y(NG4#sRU}J0jak{El?A=X_OL^((|yzG7~QxF4|K z+;Srj%!szt^fbpPk?C%Kn(gR}aN;w#0Xuv_>>+_Zd8)7f)8V%t;Sror;$zgo&eseV z(DDOMj^3~Hgv+x5J>8wElE3ZZbcRPjUdI#4ax0Kt65DJ?Uhm$02t$=|_mCFn^BLMZ z!?kFodInpwnhyGo-0;><2+iso)Ylal5iRv|nGmsV^-m_U7WzbR%{}O{+780`MwlUq zcFv36_|%5KCVNSAc%SJt zd&x9IGq@|O1#5^j&Kn1%-6OT$imFhz(k7{u9W-$MkSR$8%`*@hNCN-e(3{gLM>5XA zW4T5gXvv>a$q)6TOnd(>Ur+cxQ(AV&IUAq&{FkBjXg2g6=4YnF{xr4yAO7z>?*GS7 z`;U4kWNl$$`)@;SlA4XYwi<@-)m4ALBT!(?FTW$MendbCiCVv0KW`e1WOQ(gUURw$ zm{sFd9k=V^JR51gsIaETg0Yv+~{> z>=w)-Q7h(3*EbGK))u2M6*jow#bTAk0bK7k@2oIeyAQM7qe8`?G`ar|U*8xc>AE#L z)AqD&+qOMz+qT`)s(iY_co;^N!OAUaEB)$@uSG3k{k%(&c8>t(Fk zz}bwPJX%I{$+V=XLB6%$>-V;^u;>)t7Wtxl^h3-I=Lg`InHp&^I0s{u!v1jXRGMY^ zZ=2y7u!Z4TmqM^(12%B@}3XWj7+tDT7dfhPyUiZ2&3_yd$v|xGzHzYH-1vm8Er?6Zutx2sRyiJJ`?Nv?4 zVJe?CIQWntvhtV}9z!!42##DKcCuQM({6sQB%T(7yxF6{q+}xXzP*8T{FIS!AvOWb z8TOmhZKFpaYDm!IvgQGcG7@fQibOk8$IaC+yM?C^r_b7Lgn&JckFK*L&kqV~-B(2vwtBp+Sb}6K^4(OcH)YMw^X<7rf5t z6O!c#oH4k$W?Ppf**pzBbR=M4t&V!k#VE2ZsN==N{5VG+hyl}P<;o|P$W;MTP$U}L zVp$kHkJrH_ur^pt4iTlkJ?y6!?SO!GT{T`v#$D3iBex`AF_l6cyqu9M&Y+Bs4vE^= z`#2^i8WIoqWu2=pJ^T%>HY)hQ!CupCOI}W{xTA!C)XfP7i%+sffK#QU?ZZS zJ?l26)F~#h_r-MVQNRX85WtT^@K>vWI}6?M*Sj1l9t`37-Nk2rqFjXev! zyO3c`R!UPZmSi#8!cP7xwH2zjj>o7pg(Y@;C?-mQ=S5KZxW%|mZNn>s`1`RLT2jVH zGMkf^tU^jMXHt{s3bWDe8>de4pkSN+x(wbW1G>Ee{g=Gj)Lwn~#|m?)o!+su?7FY_gj+x(Ne zmMx~3RPR^j6?1~H%eAD;klU=XiKbu=%qwm!wMUp~?skaAk9VEF!ICi!JeXsM`I^4? zq-U9tmGNsEtHZ%e7_gE+@Isi*2!W*E^*~fL5p>2ZvdcGKG-<7Mpq6IcNjwfXJQc%a za>GEj{8T&_Bwl?zV)ogHs{~d;SOQ}enLXMK+kuxSJDrn(?+jiUu2;KO;NBi5QYLjv zgG^MhOyfB`I%YZ-2iqE{&yJp*W{@Mov1&H)A=_ol@Z*03^Y)}2r|ng+t>hvON5#9e zIxLXBQnw8~0mYM)saRJ%ib&S!qtO{F(g{z9<0^yWk|gmm!O1k-bZ#tbZpb=6cWDAV zlT;D&N%3erLuT{ouUzOq{m?i6;0+yOMDSo)MKJo14=r)&ZHTV35}F-%UsA?%J3Sq3;ZJUZKpwV2x{ZUqW2f;EjD@hgTnP&*~ z#P&92?xxFsk-J2mmV6#ZPl+gh&Kh6gpIzf;t7G-cgfT^PeY_j`_S7yPtTko zSKaVIT*xQ2LxT}RlTbl(gDSQ|yN1h;cU>|T;vSjy;J8#`0*>Ri+{ZNj?HHuW>_%}_ z;PWA@?Zu8$sbe^x&(^YEHg-SD!L}K)R5fs7=M#{={t;ZA*LFk^prF?z6lvtQnq;p# ziM&r~(7S}t88JDKoO$(j>J@`?5kFuThziz^X|fw^ZkdOh&ut%38cm-mKPVhNCT$4_ zRmtM%)BCLkmaQPYQ0|0xz>~gEkWO))gZ+&y z?i={M3acJ|FIF6gHNysT`hx`PfuhnYyO0-1xqaFxXFsJ+1SMbp0$=Vg*Amg~%$w^fS?YFeA~6IZVoS8JhkqB2)+L&+%Hq7ta1Go;fUVMTHk3`6> zxViHhGfOIM15YwK(b^tN&ljLW?xR_JQ*d8_5gNwC2i?U!|i16RiH#?ef+Q~0=48)1_}$}%5Xl3%HdKB@OA2<%nB zuJL2PPa|zYSFAx2dd4Qv%{~&+=;rq68n5Z(%aDb7hiz>YbdTRZqbfQF`Bce=E~nNt zmmXo=e-M#=4!faWnnfkp44`-Qr-nCY%7wbjZ)<5k)hFrhR|R*~QFUN$ z{g9JR44;8c`h5s>bQkP$-Hm_f%}exHJzLHEC|R6ER$L$zoMF>B%~DvGDmKt*p_Nv; zZ9y`e?Rbo~&_mbyo66&zMg8@sie}ZsNaI{=`LukX6ot6ligoL^D}EK8t}OXOCRQERq!$;&0cjzj42R z#J>3&?7uK+j_5wGeP+7+**U+Rrq*|5|FuK|&l*p7;Sv6l$#TsqUcV&56RKzTd5vRG=II6Z5y%2d=7IpjlpZ%l`(<=ysaX7E-;@z< zI#6xL?55;(QEEx8TGN+>>8)&M60?Yi2ygT(*~163U=t2i!AB9XkI~~xD|+Zygb{4! zs}PmEwvxGy(R?v#>vPlR>{0QUGID#kHc|2!gpkPg{bb&AI7!=Y(>oOa?IGAv8U?4;dQ6-Edj>(z&a#)zy}aAg@U zhs|v}m0?@Djm^j!wEDQ^FP%C;H_>bcwcT)^&W0e$$nvQ%mR8|^u-(rh1<0J}XlN5@ z5_p)r6S*BB?Ope$2m}S;HhRJeHS9I0ocLfv-0BmrQ}dBC3hM6T95Lec@EI0_8VFNbg@#74Yz`c{qLa%o+g~!7jMnlOL3J-fx!t%NpL^~_%&*AKRfwFV<_1IrIve+A zU>WfghoG^83D~3b{gmD(8C;?d|A|=wORdjU!4ptYR;}%cy-&VJpqx$Og%M4@Y}Mi+ zy#ghYA?j-cZg?`^!`wD<--f$Muxr-4aPE_Emn>L0<|epJJ~>U96$Di)NAddccc~4Y zb;go@?Q_I@k>URX!~V0>{^{8y>{i`Ma0ebdBV#PA8;q#rjygkT8dFTo6@Z6`<% zPdh7WARrhmYA5~<8*&3!1O0d~S{hF6t^1f=F&Z1iT9p>L8W&s1W@^}TIk5l$Y`Y>J3-Si4StyEe+a>ib zk*c5(4=VW*bWla;dTVetFIg6((~j`83duQzqwT~M}h>| zPk;dpkE>C%-ED|k!G0w~`HEz?WD~QM5X))fg%cpan{f1|GBnW$f=HotJu;XL-um>R zKj4k!Lb$Q!p&YXeyBu#}$JL~rr6N#vWt;TisI z`6W=@!djUB-r@vlgqQ2mDopxvnf_O>`nUVelpy03^6SZbH|fD!)?!mecVjBKg>! z9$!{f$v!zA0Zggw@3R-Ju3afUFXN`RKK8%sTcNMZ-5d}crbDT@%EF4(Ye*i}IyR$= zZ?tzWo`mVN6sG;p>fKZzxQ8V*#0^xZm_=f=Qt`~(z8ey6GG2JMF{H7IK%<+TKJ1b- zWf2}3`n*F_m$1tD2h-CQo7(ZN_7>?2Rf(-eca`izoC%i=cEC=^5_K zR9YNT>nz^@N(>eqJUZ3hLILxHku1kU4k_x`yrz-6ni8Fl8@Kx%F|TS39i;`-%9klw zIIJ0}%32y;NXD7)?ib8UgwaztC&SgZRbj3zRLvQOUnBpiBE^a2aJT8xY5DkDHWB^G z>|k|js@$#R8?5)GQ9IN00+d(xXwQN5FcK~?-A!kv~&aEDGKmV)U8TMHMN~<&?M%3l*nlH$BJm<1p}@sFz{`P01#Q7ON&HWAV3RC8YkC%|6+bi?I2VyvC+T`W_n&+W6iVbRU&_6U`e+piL4dYknncJqoDLF#T=R^R zgo*~64FA)aIdwrPOAZar!-7VBsg$DO!xhz>!bm@)>AQxDUeY1~^fxnSa5zIgmLEF= z*abcbAlPvW4Wswi)N)KA!?B6x^yCs{_+yl6HSR|;$+SP@vD>)gsyqai;oOvZm2DUd zi*EzdFVv86|_KTW#j%zHjS>P}lO;6fQ4Zuv_OmCF|1Ml4Cxdga_!++LAw2cV-_*yRldrhGyMI!n+&2;~0e`=d)7;tVIg4-En zuR;EPlV{LK?$^w4w6-B?PN0inWh5RxxSw1uJC|RKmZO5IRxu!J{v)+#ddyHnvQ`Iw zX@yaZ&$ZUaPq$6Y@LnUqP!F?vY+r%;p5y(>2`u?dNbwn8#=lB>ACt<`V>}T^7M5|V zx&|lH@SJ1Xw^WBn70r%KC%Jfgcc-nm{NNaAnDUPDE!M~pMk;;}| zxhd#AO{*6+teR=4sBJ<1gvnYlA^bh4tqF5+8abF&en2kiR^tY3p{Js;7|z&q5qRh? zfc*$G>_%PeL>KBPvmv@E_IK1j{!7OhO5t$qCZum!zpp&E#(#5@wLT61fc@raCodN6 zKXB+#nucQ^PS-ZCqgEn&CKt5qy*in+smJMQaaX4bgEC;!xvKt^6+{9$s{hi3`+8_q zi->&Qn1&Xp&Q>w;Ja~a%4xs9Fss_qG0NCu7T~o;2LEVqOE>!p?a(%=dCjmNt5rBso z^WF3ZKoO2ElmI=L6&{?LDb`&6S!Ae%x1l!wB2_u3KA|5N ztA)3$TGFJ~CpW`-1im)%Hkm8WbRiqRs4;B$@{!KBnMCtEWk%>Fl^-$qyouwZ%KMDe ztNvE5@!0PZH6;+g?_GL(%R76Z0=-_7IryHV_S=MgA~uKlB*@{80EYsUhLAB}*!e=P zMq>)^InipnJa<_&JMGQ_)rC-MVZ$NyBgm?ODODDh55G>8c+GfM;=%-L(Sy7OaaZWa zk8Mi=vN=nbY4BXT%jO$oj}=1gf$;r>>ZGw|JgPb63Lp~Ys3@iiVz z-;dticdwi6V1PGdp_Q=xHie{cnq$xk^9JjVm(=POK)lpTl{VmA`zV}IAkf9BA)G%@wHOszsK1i3T!dlr+M}og>*OQwk14D2lhGYU;(usS_E?D_C1> zQY)P`=CSQStCL*CkIBfxL@NLgwj>fI3lv(zAT#IE1PkZV=E}T=^clJm+Xb!$O+U21 zyeHcO27s0t#C&yn)<%Fhkt|VXoYSi{Yrb}(FsyFfsMaV%u&hs#Ye90!~C>v() zajdjBsw7OcaBI`Py9H*3>#*(D9_b(Ac9ME`Pv!p>YM3&-##9O$kIEC~1B`j%Jw=7vIi2i9emhW-tU(MRl1Y$VPCqRni(n*ND!$KpQf( zITCI@!)QlkCAEuOXu2FXa5PA{w&`1v-1g0)%~E9t`!IVLL|qM_+B;2zt^ts!ApY#E ztOE?NnmjB|(~v%r>V*&9744och~c!wXX>NGo%D%Z^pPHsLUj!66T}Z{L5Wtvm^x07 zR-(*_<%KY-6|1iez_*Bc*xZTu`fR*Lb$6?4(Y9~LHV;>IQzUjgvr-U+U5j< z-49%!s3i7}A%ZhG5i5(#G7Q-Q4sb0thdfN}TvC^}Q*=WNeFAoV>%~ucTNK64Ge%x9 zb}x39WQ?3P(Y7!XwyuEn7GR7H9?LmTG?o?2H8@M;nhz&elD0-T%NmUs^)WDMLAM>% zXxK2qa;Ye!!=%Lt)Q{#IrbLloFkiG7q6B8c454t@oHr+JxqijM(jiK~W5IqT{9%yv z`Na(z7r%c%EQ|XUcMB<+LA+HQvJEj5Y8G1li@Yn4p(E6>Mf4h0s|S4I8B(VQjr$2! zYji_-3pTI8i)ld8u4H79qi&|}O!u~9#}0)zxufjjKykEu$frt5=Vf2E5kd#{@iFOu zWe83;z9Y@(17*}QBa_*^k+}L}CP__WUVtz@tgqW42xcEI3w8HQ*lW-k@3-eV$nWFB z&h8tszc`Cimg-u}FAzly@h>3tH7fu5hMoS;+x2VU_07iE>C1-_807zc;*0k9`-G^u zmGR%lkiS7dKz#epYx*x){a-)y_p!e|e%jiYJK6phEQ_6#0b)Q7l6^@iL!q1k4lB_DTFb5XEs zNs3%g1X;w`7BhwmI@oK2;M@m1L3ag+;GEVIK8FU>-I=J~K`8T4m+=O}(~JU?v*#wT zuuIj7PPGEjvlSE2^8y{PoG93HwhEg(2}_Sn)TY|=gsv|P3=Yw+{JzckmC_CQ<&F41 zm>3N3&&7tn!k+*8A5i@F&Ya_a!D36NzrvnnOyWFE9Td>P@CoJUt*!mwQ}6|>EE_Amo2fM|&8?*j%-YZD z%FBHR=B_g^#D4|$Oz=EiI6i(pHsc*nc>dvX$LzU$E(Rd`Rs2Gs$uxeeoa3aLp$12Q zmGR3RpF}Y!-G*sMn6lKcdC3DZ=k2xzWgoexjb;g!JXB3gD?^@1GmtvJ5TpJsPeWfo zi5?<6$=|SbKTHk&2n2Lhvxpg?;pmTWHgflfQ4$WgW;So$}%}H#5IKC%-@;Qq%0)0Xc9Hq5Q zLcSmnReXLsj5KJcc)iMMteJ3-O(?S0Y!5Sqcry{x1-&9Ix(>~8Im|?lblv5#2WS|@ z35D7HV{>l_5T%Q;Pz~lz*&C& zNiGsYVRlB23f5`mB%OSGErD+Fu^1wyV`2OqRrjz!_nzj2?6U75%^P$%|b&%5+v2}GF4?dF>vpU!FQ}Y)Ud==Um%d4B^67YmIK6i7!~N+>|Y3&+Ww@Jz}iTNh#G6DMJQ;r;zZ_ zVPCA`{&{}r=Mj5)xY%0xxXa3lv<_I;4Oli}GD8|6sa;$IWjQVYGQkJUD&3V&e*Rk` z?D2Bfn)e-x>`!y;?;@j-GFcqmNa#zZ&PSBlC}C^8zbrZ;bgEoqzSXRAx@GDuvB;SA zB-Q1|B)67DGP*gb@TMUaQm^zqBoMFe?|n)vh|2H53+gr~3E<2ccwP~5p4l1t%MWjNbs0I~6L zYb~aTQDxh>50&F^0tn-&>Yr66ir<;)gt7Z&@SA}R*B7hOpEJJ{_=LKXBkl8U8yOof zAg09rnowLX2*bBQebi6($jBxrIARjH`|Og?i{#PyyooPR(zyGK{&Hf73bb|VsQL6@ zhA-D95sF7cBngI$Hp<^@d##RffV>D zh|nud7~|EbgV6zF$9P2fi`MOi#0}C8UAs(x=3zRY8#oGjWI@j7yAaDnGVV=O%s_Xf zt%A1CZ2L^OjMPq4sr3l?SiADBRt>Gl0ZQhU>+L*mk0H8U%y+aRcn=a->B71zYB)ndYQhZ=akLCtt({J;Ou{X4#G8!xRLFkx-rFE;wT+oj z62`URh2p^MId)96&@}2Niq0nTDDd%2?Hd*&^-Qzf^E&p63KgG2_I-#UgeviPPsjNv zLeya*`wHy@_u@YZI=Q9hG*QmRZTS<6fCsT!eRkI2+QMw3Oev#wMx0LY6pM_=eM>P0 zmDTlG(`c1FH;IL;p7G1oSK5svwKmsdmh>)$l_DN-%YdxP>yBqLv?b;Pizuti5H9$2T_v~Gr(5DhemkqJb`B8ZJpN2eV#I50SbDt4bmEG^xSNW8nxim%xiQ&Riwi(($W}}TSzZ&sz)?#`7*=OO)2W{Buwcq9Ab&nRwf68 zsMEj`Dpd2+XX0!*Cx z1?iIZxRZ8u)uLoekGsuKFsnn{A;KU#P?GSeNeL;(;F0QU1eJa_sfH^Xd|wI~bdyeT z)2i6-v6>d+3cy~R;nG=Bn7i@x>Jc12zTW2B5xUz$$li@+mx415f4U`GGRLIbvE7|cu&5bi z@ERyvbmy=c)_rz@{CN-~0c;aX2I75WOX*<;c1+H4GE6txs}4hOM{$yy1hbdv7tN6@ z&>&)TOs$z&;Y~M37iW|VHm6vXE7b2^3}Eq+W8&?PSZ6stR_H5b$tKcezfSRp{Vv{V z5RBbDy$|oJ%JT>BUyMgz7_?r%S3~{J(1wZsXypD{torXpPU$a$Dr3XHI_iJ-a?VQY zGDz~s+Tc)%WB799u5xm@hpfNQkZ*>R8-4-#mB{wnl>~Igobum8OMB7tqW|eRN&g;a zK)eh54!6s+;9MkJk|49@J=Imw`Dpz5`zadu+j4D5EH{+y_6^X52caGU~@~a2&+dfk(9C+Q4z?Uq_2O7*ptVwXRr>ezH<+UP`RqHVur{0px*DijjsdMiw zV)7HDIWhN4du%4Vr18&oWEuy1LC(uSEd=Tw=rPvnQ;ev>Wn>> z5D;kDqa15^CSy@NRyr+`1XC|T^iCCk3rN|0g7a#Zcm8X%dAa2DEgyZE-et|#X0MTi zO^YjWfgyKDzN?oILSLgA6=!~L!m9{r|5w>vLv~A4g9E_T zs<@4Z`N8--M)*YLRi=0*5Pd zgK_02;60OYS;(LJm4Yyjm>VqIfO7R0hC|$|_kz0rLPEgn|#p7abX#95p5i|Vt`Zs&1_!XKUfc#m6mRtplEKH>X4_`}TG1!hOLQyhELoOnH zW47nA|aXz*)TR=txa2V48S9D0{O4$S7yOD(1=#PooG^KRIiPx&(dD98@^2i*zXO5_%cdqN_xjhgEoz4JRE* z#C$4~Wx3&_t{N-)NP83Bf%i)QyD#YY4Y{Iw@!OTG5o+N!Nfh@`non_Qj*3q>q79TP z`&SUrsmq=2gm!{Z#t!)i&>n!qNp%p}hP>r-*_)E@)=U1dh2oNM9E@S6S|J}@zDd_| z6F1M&b0slO$FfF?hRaVAyl>`#tOAJ<^}%6`m3o-z@-XfOj~yk7i?MzW%245H^cR}7 zW(%m)6ZbAfimAA@A}K=D%p4lH6zSn%L8;h@6hFzOOdRcuj>W>oh~~`&ms3SBtF{7K zmbfj_Cb4~7p$nRa;D-${mVB2&5_#p*5`C68a91b~7W)lkz}kpufsSDb_$n;6W9z#vP*vNv7z=kpEMSmRIWs^HOAdj5t8zzl6}z^C#WM?>{& zsn{_uSgpT4wFA68oZuvtj7qXFd}q`%cK+jpOT zjpXP5zeR`l|0}wGm0Y4Kv{(Eh%Aal0$>ajvTx1PM@*fm4ML~j~z5f1(4B<3p;R{Wa zJ_Wk#{Aml^a!nl0={br5IF3MYPKxsSyaboz{?#vO^QDe5PV*G_6V{whOR$f8x(ct7 z-`92H-q?>fem`eBUU|QaRPlT(DtW=2L*^D>(%|04qYp2a-j?j1POvAob=We3bqT6C z9Foju*8@opL!;5OdCkMbhFaAwSFY8YQA4Fi$%s7AGHb9)(Vi8N!-0JZ_{r3Q7uuLm z8J30s+W2d}=CqyOWJp{m0Y6&g!_PpM{3JZ6--KR+`*@|M4^K;{gf9v{Dp3@lPOuYPnL3)K0d-u}d8D~7 zV(duTcLt9~OkdEaoA9*;g<8I58j>Z2_Qnh+AciJ?mlMn|1dBDJhzOhr+3E#UDg(Xn z+bW-SFj#TKofB;fON8Q0RtNY7diZ=`C%+h&69&o|dI)upA2Ac!kVaDK?qH~!iE5yi zs9q?-<2ZM#8Je&B?5A|&`(Yd7MYIML)alEEF{m@QCw~Bjiy>u^IeR?v zhxj4`jwu2oVA@oa(47Q|XYl4Om*hMIzN@L%VyQw_21{T!ACi4b%dxTmB zhPAmfQ4|Z|KjA12ie`$cHNryLZ1RqgC9~QISdA^hAX;M+;!ybNu85ohB}r#3*kA-E zy)=+4mczyQ0(E4YXb>XOuuk1u+Rkj!6KE?h&eX$Uv_?M_QXILBGVvFumr-j^$f)`>P3fP4Qhz2ngUhQ5W}udTS`62NyEFEPt?Ml zRq7$?>Z##s!CdtP_ZahYrb5?K;0yhauB8Mk(4bMVe>}SG$iVU`p>K#VUQ=eTVm<`> zbFxA>fi=YixiNWBp$5ZdCv<@kDic(8QLmoU(&tTPurb2)Q@)PFBnfGfqh89)VcinT z3!nVTa=Gmh6%F;|<|-x(Dk2_jKqmfGaaW;_L%*T)kelX=a7E&9wxDFv>e7b4;5~8>9 zb=S4D?aXgt#Rs}dFZ^89Jr8_`#?jsD23lRI6R)E=I!G=) z375gnWumNb7>n<#h)l^xhUF2UN^;;4LbvMcDSzC_Vxel?&ckk-L*}uuOk`x_0mYXo z)1IL|Tv7(iK^g&=+)B_KK#~T5wA~A-PpMf^L|aBH3|zRB z5mezWwSD#Gk3KxFIovjh;`Vv#z#>AFsi?`*Na-}gdR02YS5?Gy*4cBdK2G3E6EZk&p?}uYljRsbH3s~SuTZ1(x0mC_7S}rgI7xSN8>EJ z`$qO-7e<*zv~j||Sfb^=oGWG|5e!tr*NA0ykNmj^)?iF0Zki8%x*uSZH`o9Y15x@g zSqv<`Q@fg&+t`6?W_LpMZm)AYx_QhWJHd3g_*7C^+V7J|VrWl+WZn5=6N8iwLU*vb#tiGkfxD^V zE60r<>YbVfshwCuu938G?VwN$naocl=#pRu*PMc-c3`1(hC-ae%alcc`|9yv?XU3s z7o_37F*v0~C~bKMPkV#SEdU8Lmz*Y7F6=|0OLQlF)HwGedy;dH^xzDjXzqSMe-iT6 zulP#_$~hT(ep4`PzxWziVl~VbCmAVIryH*qz2AmAQErJikHuA-<;2kvGCW}K80qb) zE77bF=PZZaOh#-IR9{CPg}2f)&)36iykB|ALz?lvMomW-b8^e|<9NOr1zY)!rXC(m zAE9c;43>7_QY|95^^Q2HCRjJZ+Y6^7*rV+aqGX%WYONB7zM6cgq#G{=3WoInsk>$T zKJ8WEZ9?%4k=4-)H2g5?#$=K^=+Z9kdy2hgfbuh>;Z=?j*VUl+K})tjX^%?+Av3IG zzY1(Ui;{WCqTZUjaxZ%UiOaz`99OE^X&in>n8DyX1&&)x?7E5+#AgF+v^_9ONZ9(rF{ zO#kZig^NnV{;H$){DtOXIkyM8tjDdiSd<|Vw&vm$w%FPx<4WR!l^S+6X@ZmtB4(0> zM4(#(yUzBnM2@J*X@-UDfUwauUryQRZmBW%^zDFnK)IsZI+TYV9@3(2lk_= zk|9>|wYRDmrNG_5?66e>EREn*TZ!@DRkK)~EhbeGJl7MR4O7&3)FSg%k@Yyzmj)M4 z?OB>cFY@`<$Pyk~#){Ly%KLA1D?HqwLW5Q4F^99Tg!VcGIb1* zI9v-!A3sfkEYVcdS*p)2ArLm#j%~`UR1BLrL=9(F*r%sZxiXxy8d5L~O=pBM=vL{Q zRFEDl-vWHmaQDVov!2*xz5MH0A2(c%&TX=~f{(8UefnfR6w9dE?lB(6p6o4bE#3?O`nG&I4dd7CS^X2<+txg+joOXXqwZJ?q zl3zdFaGdXIUQj<6$)RSW3P(z9AlZ&fmIxOuQD6ZEF7XwVEK;_9M|T4OR+qVW{9_Q~ zfP46xSKZ^n#aKC8xKLhK?_Pc>KqtN4_%U=Jg4EK2wD?h8cdt%VopbC?@0u74TU`dz z)um1$ve5!en^=6!r{bQyVo-S5FqdHb=UE0a^-J`lLF!_paa&rVk$z>vSz^DY_{I~j zi4R*=`QimHcfTj|sZLpM(NtnArJ`d+^NbRU>STRdE36{Y58`m4&n6O|&%bRm43A3P zWxnj*q`$QH|1%l=Pd)(W{|!z4%>^h~e{liuK20>8b6NcE6hK`$$X4Mq3Uae5a#RpU zGl6NO&zJ0|9&*Dn?_M#iyA6YOS^gIsart(c4d)2+xp-sS2a73g#DmU zmh&L;bVbm>(EUrDM0)Z22Nugh2>pBzEYyPhLt<=7LJ0b1DpOH?_kC9mrrMDlJXzLf zEKxQY2ERnAp=Ia*jpOu;+%o?tTM-6;J*Wi0F9|?NY8QPn2OH2HS17Fs)u8Qb$wyVh z=nB`O7(y5+0g55{x)B@pmO`i_vf>?`OSgDojpeyP6|zuA>5yW+6W`(n=|g3c%jjnvaAn zY6!0+!c*xfOpnn0Wz?eb=wukZCG{~Ub%|utFH_#cMZz^5(@m|{ZWEehz0I+zur?Vy zPYCV-E0rW)uYESja;1DpgHm17H?!-}CKOE&+qTkQe)TyY1TlA# z!-3xxcp&rY3JPC{V7c{l9|9n54G=|ZJ1qz<2)hRnWr`0DF^!r@<`6a5hgkl>umCUC zHA2p2ekBrO;+LAg;(l+4+AN+Q7qz#;3Ty8J4(uF3xe66gJE1zzy?@2_`aLUTet5*z zh%}o12{;<)`TqJxDkzCGT4l}?f>12blvK!oL<*;H#J4O1KYr9gG(V9Nv#VkUeV z0>`-RzYV`eN4>S)zi2hze}pLfXBqv2m;T?h+P{lP`CR2MM+G=y=@c1F$yNyp8VKf8 zIRy|Z%mNJ!WLPvv1%VEjctvywCU&M?-tg(2A9V0-Ml^Um#Wxfk6^9P3Popy+m^G=5 zM;WWfUfW&Q?~m7X-9YGK5<&s|?Nt2}5sC?^B<9y#O$XjN1f(-{)|Z;8d51P8sH{ze zI8e->bKA*XJ&hYKr8UXBsyd-{K$Be!$<1EoC?Fb+%61~6Xqe$!Mf|RZCCHqEFp#V` zZE^X^_ROf*f0#M(UY!D>_B^vxVL$*DH%-TDB-_b0DemvmYlSnvSFs%ezJ*G(pR~xZ zi!_Wbgz;OgQHkR$&sOFB+_6v|b()0&0>(K(o?$g+x4o3~Yce`B7INwUU}3g_woU!+ z=l@}&z#URT2#+q&HIcx{2R{klVw{7)nVRaT#i6^l8S`1!D4&3hJKYpUm2`dMN^F&; z)OBVy@XODqfqpo~k3G#TnK_3b_7}ysPh3_zNI(?A#(WIINhf^?a=Ls6f!$`}wv6Uu z617rXn>Yo*mC@OvLtof1tkw{Uq-e{b94nWjGcm`AcKiX={$sH1OfQ$Hfk)OrwqAD8OJ9S4RuPwXmoiO!x> zuo#vev}vKvW=_LY7(`OW30aJ4PZvIuEh|t#Rw!o6ZSxw7cD)w*RnrS-!z;D@GDdBm z6^x;w%W)fiQil1_lpa$ z-(O2;FwIGaXL~Ls+rey9G@Nn2pQWcMS1xche2J#RQ2Vs=tMxTrOdG-&HL~;1P47QT zY_^MB<2gHjYN!Fdp85J|5kY1@rii(1A_t=%EaTL(IEOU6V7vZcP%%DJY1$Nq=`>oV zsVn$lJ>U{xG-0FEazlDW#bc{aIL9OcQ_(&ujbxuFuR14i=ONDEq+}xk)6rg_28y!7 zg|K{0968_S6LC@I{_7rLE3;d3DBwCK$M`kWJtB3{X&Qmo$QO=YZD{z(kT_G5XQ+>| z^>q{>X>}5KBQ)_gaCvEZ{Mnz)*lQE_E$bO8F{miaH>`sGG};hdo0$PTcDGexfB(nC zo-Fk)-C1>aBKSVax{g~-R3tg=d5t{&9~f%EJ&N1tnfg$gu;P3N%1?o0fRz-``buaA zj?$K*bqx_;hJ?kngaV|(fDO*bin_Qj>_CtzcpNYEX}RCUZaM@bJc{-O*?pFXQh4R} zE)Q@Bsle5yL!n!Cj z5A+b@*&H#DB7OnvOCPb`_n+yg;&XzMQbhQr6bS{o;WStzb(7)_uhicD?>6%csf_cd z*Sw)8%}Bfb4Lx{Am4p0a&Z!S=Vb=Ht2~Pq9V3} zz!-k>(F;h%Z)NiJ%dWVshvGTwwo4$Q8EW%k+}lMtN3(sqXJEg9T7&AYSvpQoE1{9n zfl>=i23c<5USY)j6m8{_y-)y%*Lw-S5eYOTL?y+h>05V}T z48J<~>HHA=_-pO3&G(G%I^o@9^T5^TzAl#brLyamUclPz=(t0g@u6*5&-_~yeLMWI zMIKf@BGCxLw%IcD=)43SjZ{J@Rdw$g8g9|dI96!d-+ z90x5T9B_?UaU`IRU~z`Aq_DAeQYiFEeT5#atorkxMKdrBHRSq+X~F1i@>UcvvgNx) ztXYZAa%3AwqLd*G2SlOK_Cm@0JSO%4w>Yu9YSLJ>6IljZy{O>KqGYw6pLt511y`k; zcA9%kKUwx!$|kWpU z-YK}Ucik86xMSP4ZQHhO+qUhFZQHiZ*-^(%I{Nb8YwxqqT6LFzQbjXn_?-g#mPn-H*H!k+-ei=RQB!n5vY(Hqps)&(2^#p-SX7oJ+3$=G z?9WK<+a*go(qD~`t0bs(%H(!xiY$Jg3a7rH)rZMw(oEZ z@3S~sQ z5ydM?$&K!ay~P>>n?5A612Ca=D4THO_#YeRy#Vn$T@Io74bDvy#k+1^3~O>z0LYAE zjN{VioU0bye(2UQn4S6$^yj8?*gIH&Svl6YeS!Q#1I#3x&>Mf#0OJ2PB>bli^xuYr z|03Pg4PA^a{txS>_V%sW|BhXf>|)WipjFsaXqM2zD+ve!jVdYD$U?C&vWgDcx-8Mf zas!wt3n(hy0v&3rVE8$Rnf<9l@l=5ryA}VUICp2KBxI{FBg^hN$$QKFPOEEwJ-^oX zhp2~UXQ4sRFq5vU*^-j}O2lR0ajx#r6;}B58N+DUTmtLee0h3Jtry-O<)9gxmLgC;g_+2TpiwM5G>8CPzN8rJ6)2!V zxjaIn{d6=7C(WMOwuRs`yW=F)|1|M&tS&A22C6(B2-DQS-|UZZwmQQwkThPDD(f%qrVHwbyxM{(|C#lXj-ZVIeO3hGNP zHy+0a1r{_}v6WFe+&SI`M1HUGGVgk{uG^q6-li3;!Nj;814J5^qw>_pV(J8_xv`a8Rr%>(kRw!$5^m$ui&P zbr9Gl56(HMwh;_^N3Z#+gNXjaMO<9Q;fZKbIhZ*@`dHF3Zzv}soDoOZF|!TYjg^IX zP(Z_xXWHH3O)_j!J`qiIIwu5GVx?igiBu))m4h3H-A~Hp6{1K&T=Epe85f&)x8-6F z+3ytQ!neHS>v(@`dKXz(K^WX2hO=U(ny_&kTGP-9PS`=vu}srI*dt|Sr7}v5KML7@ z1|4xNb7d0NXeXy;-?aWEys#MipHFo$TxQ3cIOiie}3&TbLrG0 z0cYaeH_-5~%GdyTi{;sd0B8!s>LY>E;R=0;T9F)+O>BT^@h?>E75IIQE5l3fgQeWJR z!n?4(+#e9-6Lch2o`)yR$+4ca>*G6*3b9dUND;ARzBI`^Y=0Qd`4$UO)>bv<9Wd$j zjJ1|*rLr|@PAo&Hx)w&FTLMf~-0?Yooj2llf@C~Qu%_ik59QaC^Mp4Y}VxW&~! zp(MR`Uq0it*w3DIC)Euq>Gi?kZT>yUbC+0E-^-L6)e|70Vacp8)dg`HkX*5&FqhK-QEAm%C5*A8TOL)=0RQO zel|Lt%I%kM`EKu$Y4{nDuW>HO|4ztqw-LC)5dfRBo;^R&RTkU{QL!^Zeaaw@BZ$(2 zBg_~>6o>QIAu`uBw(&eCsx5)QEUBDwd-R9jaV8}Z`^)%BR3mV%qLEKXyyU5*UPk^t z)Cbmxn9fMq!wFilJ8Zt9TXt2|OOCxhic-?rS5i_P1*9;5qX#FWU{4TMsHhB!ckl{x zbf`ojK6(HPZFJ4AvTva69kx-t4&dF(s(@BH$FH*X0(o+R|Ie-K%8La_`%SzG{QpMX z{U6ED|K7U)vzTeCe`nh7KnQ`CDi0_q{UTUZ$^s?X?q-cZqkw`nz?K2C$0dWn_=%j8 z+5Fer=Vk<=Qw=Cxcj~B#Uux%sL?EEws?n)-Z+Gv}=k;Xodop4Ov;~0$zRZJJa<)_a zL+D`@KARR8A+Xi@u`P#gYtP)%-AkLR(C<-TS3*CZywaAZEoDzp9d=awwe4ym_N!rE zi6V`+WIVL@-1hDd7GzFtDy{xzXcJK?a}>*mN}4HULZwcca9f6(RG#va?^)* ziDNJ#=8_UYdxXh1z~=Vu;36d((t5pl{NE?x|JR#6;>) zUDrzckLb}$sbZ3j(H-0FslNR&B-wTX3H(+O7Mf0msJOd6++B65wOL%NR%C%-THz2z zMu%oiSK-KLG0e;K1lEQ~SX?7)P9QAPVyBKkpp`PvIsiE2Sm`N@4bs>j>&cE)wtEc% zBX$FA?+ITqu}0oE%gNqE_W?_&-dm300hX zeW3ZhTKA0eLCMLYzu}1a5`5kDc$$ z=iu@TztO998IfcDPPQM$pahqI-4+6MtmUd`jNY@8qU_*xn@6N%SX40pVxnhtlH#VE566Jds=rOCwe^#V~O&j8IQFa<1YG?=T5%b+4FPYKJ!0 zpmA!O`e_V~k?2f=JzPU6TKLQ7avMhvaL3jyvGXI$NB!B6S8Tp8s`O?STw8 z&$ABP{p;f=&^{CdomR+D)RYH_6dr&5dnT$5Tv@ebhsy$42=mkAVUnt-PyUPt9pqIO za^dgz(nds8N8uZAPf996d&t$ZjgWb~Rrzh{qRGy(kRPyq6-@w*(1vAu z1TL;bua^A*RdwqA$jZMQiG3nBW-qN*vAd#k6r1>;UPh{{EpzJY8_h4HNbfKP=)T6g z%*ty^={PT-{#S$u; zIy+n1|99GHs5+zv%0IQHCdnH%pFcSJJy6)dNNv!9$fXpb2_=kvQbr3Z#nW{qo0v8s zyOZOzwrbI*Xw|f|lzXU3x9I({;Xr9gh4l zI*53JF0w9)4R#~ipm2^PeQ^qv=yTl!S`qmpq$ zAXezoqtsGnz!1t5W%=rrvCOZ!SQGH31|B-ZDy1OByoF5JWL)pxlBtKNn_H}_dZ|W} zbrDsHe0M3EMt9?rtIJP@Hajf9(mLAA92-3ylPe)=3*ISNh-9IO&kXUK*_a^1nc8$S z7ExLbh93K+e$cRJhr^g5F(%uR-|WUh&?;Dxv1v(as|;Kr+?XY9P$qN&0$No4N7J|G zO2l7Wvkr082JBK~3Hj8dS+$tWYI>x>g`bN-fP(@@b&re9IxkVy>ChtDKszCt&1DQ^r z_~-jRc|*bs{qw|#D$>)-QA1=j+LBTpr&*DL*#z56B{M^9C%a+B#mga3B~J2}#>(l5 zqR<5uw_B?R+kQkqE2tMIK+OX;6!CPa0k7_a5zH~+vxajZdeu*U$OG_IiE4HNdCjgeyn z2>ig*DZHih$-0<|If>P5Fzk1MYLcNKtq!Vim zV`K6%2AMJ15)^eOqn9CY-GsGv;4G3Dkd*d7viLFU7mE3KiI2cc4#~bR29iH_t4&Cr zZ7oZ54BZ}S+U#_27q=S6T(Um8G4aDUvfWy;tj2|bETq50V6;IE>TL=u+YuUMSQ%>O z5irU56B!jHvPCZ7#G!1^7E9ZKTQTD{N?xkeRV`iJibKxHv29eH1RXguT1|)_QC4g^ znu`X}p>9;2w7DfS(K^_S>R6Z0^abmR-9cZlMvTqGrb!=g?h$~e860x@`w7R{Wzhm_ z2;qU50{&KLr_XWfvnKoLy4UY(G+W>Mu;8O@*KgZL@iStSjj_7b9p?ymO&qK?9&)G+ zH;Sui-O|7UG%%Jy*f`yxl951J5@`o-)v@;VhN&4_e%!R)9fQl*ZqcXgaOIjWw(JI0 zPslD!e7Tl7rR9y*iytXGu~(4Wu10#|_S(V+eJ`0ire9}jy26e>Pcb7K!kPha2~U=D zGfvv%B|Lw{9E^s4Wev$&<^x5mb_bk)7ntuWE8xJcUlM>e;SWKwr=^9x>XVn{w z-!>y{Q=8~DU!P0CUdi7#2lwM5(wYq#ox5cMoGIdKCofEspKizMTfIZ|xk>gDlmDrh zJ)e+OTCx{iq8{??ze!p?y=MI+Fx9}aJhRf=JshiQ-mYmDp|aSI?`Y;8$LMYIFz7c{ z-3y?sjQ;D9x#~;6Tz{GH!C7f&w&}5|!yj`e#4D?0@`dui@$iy1+E-jm#awizsJ6HI z5?`$b&FA*YEjUD#ePXvq?B5gtk5UHS%4+7Ffx}`t0tGo-`)eGLJRW({in!Au0%%gnrkYx_(D+S^$Jp^)3yT} zv2uElsdMYN;k!}1U`{TDR0z$z;cfYo{8S%NHS{ku@C(6y@rpK=fY!h`VGp^Y1uw^K zrc)`q^(r zZNBnBZN{Bf^?GoW*~7_3nL3`gE@Vq{Xa;kWDCl%jM|-y#R~3B; zM3KwG!5-Y=dN}Fe+KnfcD(`K_P!a|w7aZcgu(7N2(mKMuzO2+k&r!9~v!=Y7pwZu$ zn%)9xRQ6@w2XkL$)TS>SmfvR^to?zG%}!SAjIYoRZAL#?#XQmRPTp`;%gk;r%^vNR z?>9!q^Fd~|RqytKIymAfc=O4Nrq8X8S;R0Mj~7Mgy)qj3q|U=$d7VbnuOIQsztt=&3Vc^6JZJ8ElM=Gi#Hnc62uq(IO3F7Ol z4|(j6E@@_mBX`CU{mRhj8ds1T{rgxOmv99gDD&)9#+j5yokDeeGRj@uztnFzJ6X1i z;fk^k9h$WdP-Z^Aswto8uiw+>+|%pq>*uP^dwvaqea<+t?24aXjfuDouzCa(-xHYa z6OvsRCe0E**kV(fa}T_o{_N`vKWp9!1heO%apxh)tvsUvdJePrtzF(KB6Xgqs6LcH ztk8wc6ByNgK<7IB1@zAxTMYC)>3_o%KFI&~iXfKs@8%4G|DIA+MN}m199&(LU7Sn} zZAkCujXq+fyK^QtjUd|_hfV*OHzKN&Hc#UTh*ewzzzuHUsceJ@GgO@?)3LmCJDT+|Dp$nGP zc3!Y9Y#Z)*1a|?hDe$|5t|K-TOJUWua^F_dX5UAhNv$~LFjHK40@?_5ZQU|6I}Ip4H$@h96`B#% z7C4)sOD+)`nByv)r$-tdxnSvP4f?ItGY@rUZmeCv2sm*$F@IQ)F~~~@qJWaG^!uOW zKhlSl3;6-F&j{{qkH)p&i~BZ;7=($X?_;$NXSruO(i$wX3cL2&!5$I2K>28e>+_KsIs9MXBN*VbV zXvq~38~P5Htx_*Pn4fQLsQiP7+Kl1l6{LE`XCUo99TG)>@uGL5pEW`2_Eq`aBQ0Ff z)I9sHq2qF(;qt-z!qz_a$s8-G&rIA1n=_`(u&AQFl9=^2<$>Suuaoa!M*v>^O%1L78#VNwC;y*-ihuUge?R&EjZv!EI;ecd z=g<0GACrZUhDZSe6_a*JueVZY2)#)B(Cn0?fDZi8x_z-rg3i`8b)`$NPF1rUuU3;^ zG9V>bwa~d-D$AyVgOiJBo}=jhckc}T>vV3GBY5;AXU8Uuhxu_RoEZfOeO zOob~HZPta$@{}^G>u|zlR^n#_05~s@gqJ~C82HMNSAEd=h(ZDj zxD`1USPQexnj@c!cpgU=WHW(-T}>DjZ0Oy(-w-3k}|oj`to z{dH)2V#Blx)rpugt7lItJ#bvD%izsG+{$-IqiFvw)~T~`jlljF++H~AOEHVSeD^9K zkdGb|Z)rbN{z{8=Ss=OVSJ>vFT~S!)qFr(rX?c3r7%NSv{#D*`Jq+w@=3PFD?Ls|H ztkW|ltX#X#df27iIL;n=XBb=p;$DK`NQ{o$$f-T7$_wShrtf;F9J?Fy^|SxNd?+ul zv}GTCCZGSZ4C&&D@v*2dBXXkK8;cLxo2JZiBm+=sUJR!By%?3?__AYa1zY%EAYBJ6Nj>Fv%CO8I&W^ zB1nGVHlM`;A31h5EasTRSV|Jm9*;I^__1ZoF)Zs?xl4a=IcCD_;%SJYK>wO7>4e`O%4BM%}G{j%iQ8lY7q0)h+Mg2tUMs%n?oke*Y)BP-(*wE_weAz=A%Ee zfv2Hz1%z(!spwb!oi{zxJPM_@EDozSZ0&FqH1Kpmv^7)5NVR`?o#ZuieSH0*$M6)Eko) z%CnKC&&iFF$AJ`yDwE@Gq>nnY2{p>4P}URSx$Ir=ew-~G_fwchRyXgo z%GCP0(b_kEm;87gqZX{`hIpway@TQzyw2ax4z{OWfceQT@2HdnC1VhElW!s`!VqN7D=n2NgK!30n1A7zCCEkC+`aSM!7F$7T?v%&91%%e&mxlG&YgGhxmbu@6cZWY@eZ*sP z(EX!V`0PA~PJKRvU1P)er}HI2RoD2KppLO^Uubgs>}Pi%sGrVCqFAUt$R1hPFFRhu zz9|KHq-Ukj0jzeOsq=IAj$18W*}m{=dIJE4wpI|^q$f%e;?8KrXIiUex8AUZAnSr4 zE1RkDj!AHLm5ydnn5FSZs@QwNm(ZmYBpOVi>44{)0#VC*iITg_xHCIww1>5w!)vNI zK0}IR66;8Vwu-qG>C|1Ouav$A#XI6FA{5`WDitSW-(yeIGac!BJ=BP%7$QyQqbUIQ zDDpQHn4qrY$wu^(B8mNk85tk;VZm5vj!LI%PYl*?B)jSRT zmZSCkTPP)l{r?+kSN^Z)>HmbOS&O_IY}Q8t7EU6S3PQKD=)vx;Pe zlEUn=@FMDWa>=r7+|qU=H$hcujRa8?P$~l`4B89C$wG;O3W4?ZBcmQcuiwN#zwF)E zHguBq=$rPspL?G__Fj8D4`#^ofa{fVD+&Y(s`<@A2gSVlCBkE6$n3~iJy4E+dOG`t zODkujGIVvuG!G7@<&6uFEZdJD6Bdjl>lUDew}}l{lNeu`@mMN4N~?)_2TK!erAL@l zKS?yN{p#0I|3xfK;O%yIcqPG z$`Mvyk5zSPF*8>YCKTX;VwjeJC68tM;maN4B5ooc)c#Iu#*%azQw+GfLNc#$wbebw zOJ%86@EwkFDIxZ)O)vFO?LM?#$7NMQ14&(|CoxaEfXi;Qj;T2?DZ~QU$vu(H=uUhq zvgwsd9HvdAt=|BV8HrCs5|_w}qzMSpn={R>t?*^P#KeD0p&ZMe)X3orai|VKb($pM za>)&yL3IKg)C-Uw$QHc9;+Pwv@S=*9WEew5Rb`by&VzISBixi&5}0C}1I=P?b-3>5 zEQmQ`(eNkxJg_In-HfalT&o3XyX42N4H{XWznq;Q$-kKl##t;NC3*oYGN6t2qOl0A zFNg?qYz^2dF!|&-Gsk3-b`Ob^)>Dhr;%6;0xBRf!VVX}_P6p-zFJj}7WJJh1c-wXX zqvpsG9ai3DGDsD|?=|WEA##r?*lSb+$v--7W8SnyHXOVT9UaL)cQZmmjAoy>XC&I4 zc^im2>9k}pz!bcghJFDt@!@tjnOpW#W5i8P2;-jp@9T5%vl_#BrZi6F+IbqwWj8nzaT2bmKCGNhtO}Z8cDA;m{kMjnLYBk*{Z7pqu)q`2;gFS1`gezV& zQ`w%l%OsP*x^mA=j6Qk|OVmm?NRz6@TfRlWn=MVt?(Y6QxzW4*^LK>Iuy}+1kg>6> zcT5Q&fTJZuH#mKI^(oFHKQS!RyL6qalV5R~~@*cm2Y=aeC@6tzFpWnb0T09T;1h1K>FB zZ>;tv@PNU5IQ`)iRBcVr=NX5Vltg4PIz2@-#hJa zybA$xJm!=+pz5VFtS(kv^eXBFT+hUN-Llb<)cDXy?b;2ppWW35dT(|XgHvy#{jG_F z>#NH{bLjbQa>nrVh0jl5*)AF&!q_n+S-?-_?Vr-Lb!)sU`UT(#XR*aGX0V}j7rP(F zm8v*heo)eQZ;cHaeR9V(4$SiCb#X9u_d~g7NYEV2L%p<(E#5vW7ZD5Yer23fuN_%r z^e3mah^zkm1&CkdHq}=nz`vSvAzU9L~(hiKsnCpOFd` zwUZ*{F+zZaa|{{Ill1dSp&05S$C|{QbL8V%+HMjZm()%!vNm_3^rJeoQ>%i*my2_3 zoWArFKoeoZ8*V3;9@wcFq`;@GM>Y1hP4^lRy=z z9rB2TR?7#syAxLd1jcIbz`OchTz9(X?O9`>kYN-5cZB>{?p!cr)2!2k7>$`4s?_PL zykl;|_Q<&8lgL5DnCl=eX(qFOejzwREn5-M^9yrdV#W1tSJUY=_ zeAte3;Es95!UWMs+z77KctS8?#()Gs4REb{A@zB7knpmIu9a}T7wFE)+%I!{yE;EC zURzEN$U$u}9!(g~ESgSib};w@C8al87^n$n_HM!W*k@45Zl?B21TNn6hyqa|?jYW+ zc0+3ilxzHfM;*UYM;{GC3~DuRk6EDYKYhkPZT?IeSVv)o)9z>PZ~V#Pd-6Wdm%^N= zI`#k{?08UKVvhDbAXoG!4tq_^`0==_Ax-1Pc=)2`8C9<_riBW{BOso$ukKiLQW}Vf zM}GRaT0b0p#r5#Ui>q{uuxl9O$f{_2ejG7VZMfG)$AGuYoZNbjrrsdfoC~{Q#qOB= z163SVQmSG(;+}cP17wZa6ECj5M9QsU_`hbaDF-Kp)M`!h)(weRY>7yvqciOZb9y!f zS2Zw?ZaUJFuGl*0reWg) z)`xqz^^x9QY}gi2VZmpY3)K^+YTJHTD_;2&mMxOd zGPd7~F;)2jo4wV3QXgQ=r)YT(&YRp3PVYf{HxBlk@}H#YbqiLSs7hV=RqB+_)KpxE z&b$5Ku)L*V>a7+WTDM&HJw(%~z4eW$B7Hf}*6*V=R|x*3UC|i1S7T(Uk2P>=ywv+f zkK_B-Xzk%SMTKD$JT`d!uHy4ewkUnJrYZjVQ`3K!@>E5msiWZlbyX~jpFNcv8k#nM zSc8(*wNY)>)T|mPD=L-5nr1Aglz4j5)+}vhTk5`=;}uZ&iq}>x73Ag>$5t(yDr6JS zByEGENn6qmDC2_V^-8bq&1^!lJ?U`xrmCHAsO@-Bj{tC<2r6)%kZ?zEya6pa?iP=j ziDrECeS+2l1Z#g#N3vm5j1fH?x9x>-J^|q|u3=Xz&Y|Hsk}$quRUr8eof?HPCKA+B z^)e^bVdS@EOC3v|HtF2iR2>&;uo5o7e@SwtL3f(WzVUXIf5Y4VQ#XS0->BO^#)<#C zu+mpWTUq;CiS6dJFTj(M;%!;*AT>x^JOUM>h9xCU5Rir-TJ0s#%0kK+NlxCvb5mTj zjpBX%A`j^ zDy^r(M~*8GQkdXn+Rsk>uC)nQbH|H}IZpr}Gdtn=4EkQ+pw*v2ZD#tzk44);ph&=) z>0~@r%22wK(wmwdY%^&jCRcvTPHyL1XvjN@npxn^Wf?;s%54_$6v~z?zNpUAZgwLs zbct*hx|yQr5uzeX_J?3|)hRA;PeE29agRjM*oVz(>X8!-q8!A0C?4_-Ft0e3^~iMG z!?C`J$;1>YE;PCeBq{j)Di3#4vePBZR9898w*nPcvzD7%?$+A8K!cCXUWng0T5jjt zK$eNq#fz4kqtpSb(H>L8fi+Y+?=QWCsi*E}_wxatpBzWN)2`(A#D(IoAKtX5yso7=?J$FIu#?_o zl2dm%73^VN=yw7@pi(8bOgRpqG97uwBOsjYSl+x#`^jWrkeJ5dM>ML@My3zQ07Oge zf-WIiKT#4{njC@4;l?17+B(9{2~T*6->V}Xvoiw>)=+3}6>%{nS%$ z`tryzvb>+5t5K-z#Q4X{v#og7XBkct4Q4R0iSamV`DGK@Au0)MFu1?Y$UkuQH_Ag# zZs6prN(DBBHf1cWXV%d}fkNM@6MbU$!*1~FgQ$Y0h~G}D3ndqJ4_d#=>iaGLPN=+E z3hM1@>g^k7Y9=109xnI`R9W0NS9KopJ6E3`FKgB@HZgenpUt<-$8;EP67znc@$8m$ zr!8>RN_}4KW%esWP+1zGBQ#wsm&fb}NOlA&Wq@s6QSy$gCW>DwW%Lw#L+mec%XNw# zaeR4`((ua=5c3AG&d9C= zol>EEKA;@Ma)#(yp6dJCA${UW-vi)c|F&UWs=pw_yQ=Fg3P-g=M80w@a*>btiqQEC zi?Tj5c2LgPCS;ea$zyDdNf7!(kypzh70ppFXNb$r&B<7``W@efz2!8duipxP`jYiB zVCrX_dYK#+HVg+(yM98%_AOW$4TtPFNZ7oy>Pn^j{k6!1=20I&t1EY`{|{}4X-94g z_N^{k`Zw^N%Ig2U@v4d_h}xMb*jw7U{Ew%@Rax5}={rdc+yeb{)$RaMCxn{{FLPM7c=6&4cQctl@vg%-hRh8)cu;@Qa_ZS@w~+Y7G{Zym1H^0SVRmKOlU_HjyZ+e zy}M<7Yw)H)Z~Pi}dAS}~H4DN}kYtd7jXI%D5$Q3HY-!R^Oeh{hOvg1#)uFOw?-1VQ zTdR}qnllC#R(#396EmsJ2Cb&zFW;%RanFsL{?}k3A7TZC?jR~`3TA_muX~OcS3S{u zUXR~$nf=ckX4+^2<(w7L8fHRRWMLSv@D+*YgBvXkXF44x# zO3RdCl$*T2nuHcd7Tr%r@Hw0@UZ<&O8p}_g$LHnBdW23G@DHFFz-hcCM0z_8*-yna z-hqeyMmp;|GCJ3|gkXm&7K=4dr^Fx5DuCVu*2fRuMApuoNEqK{nEzrF%`&Z4bRmt3 z@0qVJL>{T3nAmzC5fstfE)haNEeSb&`>zrZHzezq-=@{QCas`}!Ak z^nbp-fAK~w8s0w2C!T(K(ocwY4M5m1;2>~q>rA5plECW;>lx7lY@opd0z#p#3{XN! zE zrks*K7(e_LUuWGtudnZW^Ly`Sqv?S(DD&ABh%$2EO0?Wu?e-90ZR10WC_(fFQm})@ zf@l*BT*^(i2C%CKQhw1OVPiES1!?X)8F8V;HJ|EaWOrV+s0Fg)Njo&TK>8FE^setC zM%T5>CYGmKoxzj_2}kZLnn#lRNK$9Qj1@{oC5d;CW1Jio_ueS5WJrsqcC$ki6|5Hs2Tk33z>F3KpNR}c zm1_O9i-NTpKygs+gS7FHd1249i20_6qxTAAWbXF9Uq|jZS>0G&)cG{d&Q7h-P zMMSX%sZJH8LP5^%xQSg56I6LM=%Fyy0xLGS;9!;8zcjx-H*;PQ6$n0{LfXoQR4S_D z8|!)TR|yhaqY8hjez4zZU^=pJZWsb% zIYUHf$F7{t7DK+m@$e=WbRd;XO0jeRDNd{BtO%lJcy@mvqC_kL7M%EFKtyA2XQGj9 z4b&ADdDO$W4Vn>8i2IL$pdRKkSdq z+ro&d(xrK0m_=r70S%dTwtQ=t<^|>f%1j1<)9=BcOUjSd)pmVtVP(CJ{7q(BO!tiR zxk$N7c6vYu7dE3Eh7b3WnGqk_#U(dV^5)I)had<(&FCCsT4XQ=N=7TP<<%uy4nuEe zN|fnfKzw2v7Y>=8%q3kvotUX6Q#7Y1+}WYLH${p8O{-P$U-le~=0i$RT#!T?nKL=@ zsO?4|vVolKKeeZc78f2a&NQ5zBk~=GRt4CQvB)y(lz^8w5$@q$^mfAaqu$l+Q zs^cCCgh7jLW?)Vv6BUcpA4)KQV}!YvVYg?LM~V?skg^{_+6?WD`vSdne~dd%4<7mD z41ar5@mFB*PdHXi0quMJ@tg)lgV>goff=SgJ=__lRQ~lECqY&4J3sQ3XwAhf6O%Cl)6Y0rQpo%H*+&EgRbH#79eNa2Gg z^4z{AghNxPpWA1kV@aZyxu&_82p1Vn$HPVBMY>e5E^s!VIrj6L6G1>(>98DkM3`v>rwFbyxU z990qp^>&?haOoi$sUw)Biw0XbGnCAK=RKQz?5mrb>mSEEOBolatGw_pHGeQp?RsM@ z+RH=;xOay?hCDs`F1>6#BM&;Efe!E3GF=E!M%Wej`r&- z2Q*}5zG%PW!aB-e*V~5ce1dIOHGUZ!;;U{jiR)e3U*5noXHAO7rswOl3a^b3AzEEG z>jgrlMY$wT-lvm&!rCX5(dsGz+!d;l4Md014t*zOpAJXn-bXW+FBeZ%kF9SPzQ*A7AX2D$e4x3MsfN{opqrba!Zlfr_p@GeOIhz z){q5{G^VVE##y#eqXFcRCY?LYY66#RIvqrLU!1o>mSYl)=}IJN&oePJK%BOtbGcG< zFRMuao%u!eTSH<$jW&$N?c6J0Id^+h4^0vTNCiuLpf;i+8tr|pWFm!hvWZ7sxRXn> z%A_Ll-eZA$s{GHB22J7XG?89@y`4!wS#!oDlro z)e{Ui4)7yoC0-3biuCdra)Y2MDOdAy0xL|vk2(rthQ69K@&~Q8tR}g-^3(6~i$CkM zaaNb5Er*&t?>x+Hjtj--+AN7~* z`Qsi;DIT(ad=R;?WrBz`@|Po(!AeRdl)pI?LSHrMFfSIuppTx=irP_>*_M+9Rk1KW$<&X*y96Q5yE6wzHADut#q zRj{CAtC8FJ!lJcGJX}3p5v4U@@1q#lzlX{46{_d1hAN?$%Nq0v&xw*iAv7+97GtL-bf8Dkt0K=TMF?@ z@1rcY*Qd$FXl4srkx;%faIL^IYB?pcA-&*fN$QSKh6&Jpr1`K9E~4rY+mhFtyfo*O zxvJc62Tgr%1Zg`dyUWh4J9ft^b>1%cBDm3v#w;FE8`Y~jdZ)?0Liup-&&v+(cuM9l z<=CB(H<@Ho35NwEW+D99P#yu#5M$h#nLaMw;?65rAt3N-@gW2WYHC8)<8g9Wr-ygV$2yf zJn;t{dsle_?*wpdy}(mF(N+~#W-zyn;O*x2;Z)a*tG1>jKv6yY+2jq_Q{f3kjf*+C z;g$>v~ zynx6dPXE4n%^ny_GkKJ^ZDbFWWifkPc>J z=?$8?ZJuG@pa15{1LlzF)@|lh_50B!E5Z;Q!peACRWyHSOrWN=)9g>|ONV;#3g^uo zpQ)xTol|o{sdu4J0qeo4a_8jXk*ZjFzk(rgNfQlu4pTV|!!hyW8d2Ne|KMY%$)8=I zY&xO;o%?(=%P&kAo#%hG5p=Il@1$44eV%9UIG6tCb#Q2Jl3OQ>n-{hBt9ehLHoG_{smPI!Cw z2G8X+RTl&=c)@@-mpS-)oVp{^&8VDl>KozrMA`|ccSiMoq}_9T}Z-CTW3X3lti z+JPyL9)*1T<0D1WIHwY6%^UO=>2$sA6`K-bzlcL~*LO%)lJpwP_vMuYnv>k2xjDc! zbUT;h12XtAcC|7844{{3%$M{ta-wki3)9|drlR2M5WEwB)7Qum?~jUN^>EJv|Eim% z_s;z}Gy+2Z|MB%rL4rkTnrYj%Z5x%gZQHggZQHh;S!vt0?MiKS_ssT8$Hu5JRii0b5}6bD_k?>E+@vGc6lBc#8W3GExRb!$K%@p ztlM_>`%HkaUB7}JGuG#;yjGHyQglS#K{bpQ;G;&5tj2+wO)w$tTlq3Md(Tjg=iQd( z6XK65y6CE!%xd;K#shzH>+0XfU8pmE5smz^xItI>w zukMmUEB=mcOfE~JqDiu(iMLSyDHc#QH7r~#P%||UFeRpO`8|%aN#*2_yLbTD z4pVBvR~rg_+e8C~`#ZJmTSX&q#hB8UhSps;WzVbu$nFm9yQL}#Np}mjU9#jpM|XtV zwYKRVuOp?Q`JraDAFMr6(Y82h;}CI;j{ditZW14N-N7XkW{#~sJxO!s5gOPtk_J)h z`jS`j;)Knm6fcH9X)7|il81jhlFbB@a(@28PgMDAiUn2?QXZy2QYX=61SsIjO*59xdJOV*Sz{%Chl)l!yB*o}V1u6{~J5_PXPQMi6sBDMcUb#{b1lfo=9OkTW3c*>wh5#HVQIwe*_S+MfpGw<@r8& zRwBFI2htE0MXU?*MP{rzEzrj4ELt%>E%1I4|0oVF8$v;@j$F1UyVlqro<8p&0nqI= z191Xe(Wu-gLmB(h(>) z3ggK-)`*HCc<1$p7YQU@6NZgQAex9uzVa2!MDoJMu(SBY=pNhBV9x@M$JKIs3yoo!gY;W$%Zjl@wi#n-#ThZS3!y1_(n~-xV$5L7 zB1URPl$KUZOmf8nD`*65%o_LSwQ9xTf2+^;YBozS?m3Y$Z>p+9B)eUK@P39Gp)vG` zYzZMupw#bA&_J%z#xkCMaE`a*sgn3h0emjq{Q{*3>`{SiflZ-R)gRGc+NWEDS*B&9 z=>>lW%S6+f{q+e~agrD5FmsN-`jJ0GJY{rLU(WOPPjQVB;+BZ{kIPl%2k`m#h2{N+ zkM$oW;{VbK|J>C7>&~Ko?5xT^b$0aWq?mY+5}^nPgl+NCNyUNC{c$n`7QZPW>nZ4B z$B1FlCkNBf1vV;dnp-R?tM>y{v|1H4lM9TaI-A9pZ2xLhYc~73)Jj!1TUMHXJMCnS zF~Hzwza4MAPxGE^Hs&(N`nbM)0vuNge`1u%b1quVXspd|;lw^^NN^*?I+&5~EAaC` zA+Ka&PjV_SFSDN%v0hZyU4_XRB+On4=j}!gzyGZY{KA0Kz8-B>M6FI*Bdepx-ZyiMve9FGp zgq;j29@f-3!~&U5LIh{GrIi=y!j3H*seVS4!p*+(M~j)A34T#*V@HUvdZV+hGpBadQb z{bk4u+JXw@RbAIfd+jo(n$~6J58xD(%E4xsFGfby|(i>L#NAGfdeaC^wKjV@H_*L$u{Oi z6L2waIW|scEG;vW(r>;mo+BdXyzvrFX%f4t#sYuftO1!tQwP9_VJ5cSdGTx0W*3?x zLnvOM6C1m+^5sam@!Op;@DC8MFN&h{-&sePEt{Hf#hQj^_tmK9wD8|uodP>VYAg5W zn*fz(ka++uU@-%Tf8IcVk>zPRhrlGWbP5B)r)$;(D962Fop2wZ%*z8Dlg4V61P~It zay#(>Y1!rX(w|G@fh(k`0oS*={D-Polo;Z?~Z%$7O&OU_)L=_|gF5TOaNHk)b5clhMAnSFR}uv?&kjRCc-}G2`yZK2vSkx8I$? zM>N=x5v_l*%=GMg(s=x7U*qxBI`_Ha2g3ra>}!Z^S1RDjyJ#)wWoZ7$*$3gTC?)ZX zS=-c!`w-g}@JMNL%WCH{km}7t=g`scv(};V8wvj=DMsSJ%Tevt%g9jrc=h;uU9~>X zf)f6$87{O*Br{O2ksPd~0Z?mI$x~-`8 z8<9$V2xH~)24!C%r0`kq;hw2I6G?^fu;S8v>DN_J1xa_4Jae~N+BSJ$(`9ZL0iXV^ zAmu@b>n0~kC!g`|NnpBImNOI8mI5zILc5;%IT@xAvvRaDUCIp{mPa*a%K_xhezDI?FO%N} zoZi3@{n_a~>rZkuS|79fbgWr=f>8xM`;`mWSKvuGTA|^#_Q^JypzmCt-cg_MjF=B> zSaiL|S|7E0ay&oA4uwj^P_g?~A2t@Bz9helIxrcvW>qYL)dE2$(Oq@0_I~8Zx=Rq< zOw5EUR*`HH-Fd|0khB*?|7i8}kb2S)7bW%l#km9<-uGbdhdY0@erR7G_$#}~DYCFk zh3(XHH*@CF+Z|$}7k&?*_wR3v*V-aqgF#$OZ&>_VF|HMU=G%7Xz&>@uMng)IGKY%3 zY8&T@9J>a~Ot2-;B(=BC@l=(K$AEmOg{@)_iugLi=k2Yb*4IyIJ(bXaAo)wJj~3v2 zT3?0(3Ki2bM@V@+p&5y@h=XD_Cj92%Pc(@TYxY=LE!97t<1H)v3qP@(>CM{0^5aM2wOsZD5_d ze34a6q#d;-m1btH$F{Y=*zzh?2EqVk0CvhURqsW1dvofZd*EkX2-9Zw--A(vwGUCP)( z7Q|+$FV_881D}i%TxKl=h?{GQx`&V!Ak)WM2g=T9_=L-bw0&cTffQ*5iD-`9Ag_lU zH^XdM3{W!+3P3+O6s*+uP6uxMTO^dd5{{7Sqq;4dQC}xm=N+g1*u&|dK{>#51W#a4 zB(U|&!em%Raplop9j{4FqhI&Nr4nv{ z{u49F5VXo55Nj=(zo{`36bd65lsDylC7PHZfH$&(5a~{=PW0PH`ospQEih`S@pJy=&+g-t*L?LbV~iU(jy$(F?{8O z^b2cxN_ex0H;f}b^|h;u{pE1Gi;I&Pc|RD>Q9b()yQ@)0r_`QSrvleA z6LH8*bbEdjARN}L6t{FC7oj98T17J^`r`Sa+WKu&96~GqXyto?_7?p(^%wlYex*VR zE5Cu4c$YP_ENnGVBBr-RYv@42HZw^rq?2;nV*z#TfJwsY#5|$KbXJd$Zsr|SsteFa!%|&TA*?}UL3A5GdQCb+ax>1cWn05%8cJxwPjD{1h(i7O< zyMOjw_aD9B${{N zp(23grhBoTFIdIyS=_a*pYHDbf?Bu8RnOQzVMWpqo6>fX=yGwJn64jlC^uScm9G_6 zd+__=SB-)04g9}L&42U9?uWDx=vH73?Wo7R$G)g~MvC37KS!aKB;ej6aIe!n=Y*}L z;|apz9jzH@2F1Z`AZx=)GGN=C<0%i|y|~f7Fru7PM{U9k$uWvbZfv-R1@=}3J>qi# zItkeMYrD^w1b|omiEZnFQIPaLLFj4}KQo zd`wxCbfPYYy0en_W!!HERYA0V04fM~rF;+;WGTeIhr5~d80O)47eZ|5t*VAx<D1B=CE4R!S<{y-h`Q-b8-qr7KfV(&dR*xse(j@NrG#?fT;>!wSGZM|5(=JE zg!nBoz&B+038VGi$nxS;cEF$;i#|KH=0&P21g~ov;*(r`>9QQp&gsxIgy55z|3)W# z!^`9UayAQpOGLipcFV}OU)KTd#UbF!cC4t91ShFdM73zlMKc<%4wmF_=$n{;I8<0t zLLD*8HCio&y!(mrl%vS^&I`?HFUzg3rn2p=qk@}7Sp)4XeoTmyt3swimYC#dN?dG; zlO}owsIH8w{t?l&KZ8Q!GWz}VbN-L*Dtz4l8UO$c?SKBP|L1n~Z)R5cU+SX&Rt5a% zi|mlaP`=1q8^SeyI~~ADluKpVGp5>GDN?w=ICRKTumKX1G-<>pfSRqWLpR-gBKsT@ z+9j81whBQg5H=&83u~35R#55wWv?jNnJj?}fRZ}keaOD?cA8FaeE-N5lLLs_Lk6}1 z+H&Bf($1_x#jbfQ*mMB42)M+3&(Seo-4-%%{fcoW0{)Q#VV^FoK3u+qqMZIl+hTBw z5?UrJcIY6}o{64jX86vqGnOULdAw+V2GWwjIGrR2u|?Jyg(|v_n6+uo$qG+BHj$T_ zK5zCOv7KBCsC>54*CZvFHR@J{Ko$qBPwj`hWU5O%u_j7ejphZ){>i?QN00L&mg<&c zQ%TU?!Jg5_2ZOyl39#dkf!V_ir~$=P@j0o95+9HKAkPp$aYw(w9JM)2BKc`RQDEYgNNjI#p)jLy?)t45K z2;}ouR;O1!ht}tO)U@b=qj+^|s?WqG{%W%tv}K@^E653K8tQUE(BY5`D&~gM0ig~u zB%_n0_U?~N7d+ceRT6EbHZ7`|8CfMz(6Uz0@J9T{IVPS{|6o`f#Vj6Mk@bDd!ve7r zCW^{@BG5ZKSpB6a6U4qL$;HK6qdmPY5`qbx?5O_}zbMlH;l&kKk@eD%+U49GAU`bQ(0BSIlFEP82}!-6|O;wAV0)aBSo z*>3Uvs3KVZSMAz=&fkyr@Bc2#))pqV{}r?KQ?=%f^0Oh^H5jl>2nazCAUG%_AtXTr zVg*uI6Vd5FkRiY->k2@_4e%8 zHMcY`i)m>!f44KQWm~iPvUy)lZhKvGesiAipXB)LFNxs+*D2x}N7a#OCj`rw4f^)qW%{W=`Jhtn6&`cbGR04Uav%!G-I6M1;yl>EXz;6!vm#jHo4D)eMZV3r9A^;arQ@9Lc&#jKskz96E6HX#GoMFd(p1 z3TaAsrB83lToxuld3Jjckh|(*by5{|M+)>=^#j7`RmgDpxMtz&E>MkBLtSblL}XmE zV`)QSp=Cn(<(yoMOF4V4ob~;KoI){qi4N=`VAwKU5-^~Ou708LW(>)R-qF;I4NJc} zDdp32I9U%RH5IAoC?>N>0s?(dJqJ6Tj%+f+b*X@n9h`UhmHWL)fh783EEYzg zdI@DF=RfmN;hMoBBgJG5`h2BGy;>Y|aJX;LgopJbeGHvOW0~s1cnm)#6tl&!Vqupj zX3MD`3Jp2kRpLTRrVG~2to+BtR^y@V)P9OFG3;435koDl9scWC$#tNLSboRC5FE=Y z?|TuN@N$R`_y%v~d8@~AA4{8BY$1hJgbP`(*1T;EIC-c53Z_9T%5GOzv;9QT$Fc#%7|Cz`wQ=BuLwg4W|9)MEpcJ~b+gzx{ubGF?}sZhO>Yl(`_G0<)qdu zAiVmiYF4M?)^3DcW|MT^CFgY&FSb23B@`8PPA;>BfSJ_r2@=p(HV=Ws0A32y0_e)hQKNYP3G_Nta zJ7%Ekv&*Z?YZNFsqE);>dK5G_S2s78S~#&ys{9k0G;c1<7G_!ZQq*Zq%x&?p5Xa7s z@xj_VY&7gA3Xu%*C7$}8;aKT(UPUIZ!PWyeGT&JKw(QCcNp%u&RU}1{gH@u3cXA$+ z-Ld^GolT~@rZ_qRb5a|*u@OD#4^%%R9h2&?+y&?%LExSY{2@XHVQIk6?^4&t@4F z3ME*?C)526Y#Yi>UDWzI87OgDhftqO*nfiVL;}ZjoE!cWK+aOhe&pv!^JUge%Sy24 z>L%%uwP~~{poy!-9;w1Xd%QW8jiAV$W`(~k6Fd;*syGr~kcY{A9-fxJaJt_w!gMe9 z`3X*n5UZIw9EtE9%~;EWPVz;SfID0Y(zc6h#cv&P=+@rOCs8KbO?lQrN!2M^wa2T2 zsAx@4$Xb@;30g&B_1~vpMqY^7OHLqGoolVLL@fN8b%hwg6ZFy>z%1lwEcbr`&C(HQ zGIj*q0+ba7pgxaeGhY1&h-8a~6}2bEl94aH!yxV2f0qJwRQ)jG9K2J^H9&0A5d zw>~S_D)59pf=K$ zv?m34U;!sG0pM!eK4a$VHTUNGo94&Z1AO8&90YTcY4IUs^F?~B=;`-8KhWm>fcW^5 zJ-7&41INHs&i5l;>7#Is?n`m|YK6w&f*JAgio~vTYul;mfNqX%`^&I>9*OsS zK-MLfn2*nH#k6P-kQ%4ZBlI|%L&Nso&@A3AsdM2{Qo zoc{y>1g@h7M?<^Yg7g>c90W`}4CSCb5;f&{sJH%i4I=))h=o-zUpWbC?yKL_wuUX6 zaAWGcb&P2?yJgCQ5@;jhjCHnIjlY-q9rH^{b1*L-wTmdVOAab&p*rZ1jVFAXrt+75 z_!wdJr6gbN{J4zTqEZcmqB7<#`;>|c&Q39^HuEofZBjeH`A9E&8xjs?!yXjY= z@n+EOJ*0h-ycGO@F$Wtpe%XdDGg0m0&i(c=-=B#xJ@!+}kVP)kI8x38?-(K!ey2w%kN?=`mo4tlifnykBASu696KCghG2s$9+*JaW( z^`OA)oDd#SRmh3-!lRJ7w?TdAyZC~o@G90`!$nQ*E@2SVs4T7eRiIOIESsB=!N|%) z?*6g{bz?72tgv)+a`T)Gk7jU-ZhhySe8UrZP0j7+7xDmoHoNNM8A-m9ecw&ZsPf7#5?PYR+5I#27pdrpEb^;6ura>`b)oY z*NqAPY9EnwsqY+QFpAq1-AxDvqpGQy8+;oZXYosq3vW4M(-VHku6b)Fp;-B4|9~h?+hk0F8-eWid9&5%#AM14@cAGh}<~t zR2YlQUfy}e)ufCQ=Wa>!UW5JZ;cH5hCC$I`^O4A>(s>n0hXMQ|PMZlHG#nc$GJ?Lm zt!f`inbcNDW*=>llnte~x(<>X>8FHdv@hr5W*}g20RJCL`yRyjsP+%TruDxVw*S1G z|LF<(mxcYmxKO!z*#QOwpOq3w*x~@R`bN|^2w*KlXe1>N;R-rwSxZp0a^iN`??}k- z0QlWP1T&>_|GGo394* zVjK7BlulL!&j%-tDYZDwR4a63c#0WNsm6TgLpp3Xl_b54dysUtr`DjC?l$kqhUs%}M|2#R&f3I6|F3$fqzU*Je=cBaagrxRUZb1W-35p~lV}&%g zoPuvrS6!l_XoVClC}9}J!uEHUW&+kah^CRI`CB;m?`m(}OnSL-$#UPs>sPG{EZjTX3Ihx*MJ0OFdhZs z7VFZu^#>M(TBqhMm-(a;}uMZDyU!n*gN;O;@>HAr~RkB8vO*W?tC| zl{6K<+e*^ToGWKf1#gk&+$8li%wNt(4r_flkr@q|^IY0$Drf2fY!TEz;qc>(_NXf$ z1+XXOGpJ*{dP<}jwuwdIP@rQfgrHG(ocwLFUmXIcZ&)hVI5@Mdw5U($V088zjk!@T4ep{GKJGFfxV@dRjOfgpv&^BUATUAVWequUU>|nQrsZv>Y7d81Az3)x*-oP>NPdg=UZxL-CA?8fRkq61$TJ$-6!puN7 zuyQGp^9;4W0rFv&wh2p^G^nA7_WLmvi4%tL2sWq?G{iMT7>A%fM)}KMf1>bcqz^R6!XWIe+8|58hN)jtK;lemPXpe zCT&s*sh4;k>*P^BD6{gAe3PNd6JCm?jTmY7r_3ij)dSN~N*`!#k`+l6J;Sk5h`<8v z1-BHc=alrhA(L#Y?uT!ty1Dr`-<|svIO#EB1<2+q#I-c~qu$%ACIGO1`@1U7>KY|7 z4iFQwNEqQlsuQ=30l0}CMPL9<$&f%)J~qk4?V6V0;}-sXP8vk_6>xP5Cio=mhv9Tn zu9n;WXJJjE+MrqF4}j9}zl=?x0sq_B^gjU1fAmV3IQ}<)8Lj-SiYGC|XUINx0ULJ++oi>x26J1Ye2A8?l^Jc=8Is7Xm+P zR<^w+F9iA2c5<1X&b`z9(&^UQ>Bsx^DF@(Wj&W*)0e3;=W|Xgq*g*GjrvdB`dT4V| zlk7yhHd<}Fjn=|sA4Ry-Tob0KnOURHQIa9cz$Y9qSxSU@dLBWH>ynJ~lWj<51#?%R zh90DkvCqH|Cjc{m6C}%%@4Kcvh)IjNwtBd(9d35UiLACd8AQkR;mP4yKen&DQom76r{ey0s z_-Q=RYLUdPeAOb4jPBey9xeHhPaVLK(Nc#-?a%{ z5Yr#j*>lwH=O!tUELYW}XUyWHN&`a!yQKq0Y6~q0@CcnVGdWTR5RHgW&QJ3&6=>Wj ziYSm}fzzyz+1Xe|B4Nc=_f+fyeDpqTTYLdb!u&uKd#uJsHs6wUE0dSpWR1P zV>OitQ_9r6#+B<6VuWh7l`_qkb&-7j#R+k$gyMYa5(8DS$W^&SgfZ~gkCWZ+OLVWh zuJ9XcMC>)qk-FANBH7qe2dd)?8z=WvazAGC9^)?#)^yX`4p$-J74l1&=K}=q+>v}y zw@GC)`(=0p`rj6H=f}NQ-%s>r_OWIXn-%EavkmexwbO)65z$=nt=>a@6N*s1r<#HU zKp7(Q0NtPZV?|%!KWJ&}w%|O%fKyYaw3&^Baj7rx4By~gHiVPVMgjKKC#z!9LDR}| zB1ZUSY20SyJ;WWv`W4E4owf zuH!k?)lT6jzIs=>=QknWsXI;UPhl|odRsd(X?hq5>GsEPyRwH#veD4 zE3c?I4qQoZZexO65_IbGIWlX_1Cm{?mV)WJGU3M$=zl!gg$ss)c|Ri_^#2|4|ACSIYsCNc zTqkS(Q$@sgLbgXb0NNn18VCXr2V3Bu*8o8x5(r6Pz}U7M$CD5+CY_dE*M76!k>6Hl zuCwoGtK)#^MjA_<$NFR ziG`b|bSw}Ju@rUEDmIqbx-{aNHwvSfFdx}H+deG6b_YCXpklLcR3nxMe(8I4;u>Nt zn1gi^^Z7+TzA==~MNOHEgGSfn(ffmfM#F6-O99zX7ef!IuEK@+^aHq>N8MO@GMqw+ zbs_3;>|4PyM>8FmBB!I^_jlzR444}+;Mj_gFQ_xGoK;)MVzL;|HMV&zkQw-@BR$A$ z)4`muzOMssi@S}Qa&fvi>lz8cME484Yd6ZJwz@>(Lar=&5N{`!@VW)e#@kGvwsZ=X z(uB)eG0d*xLahaePZ|2vxj+w^m>P@)8l|z_EIcnxr>nUITianP86fq_=9-HfvjiHR zw-u_!o4Nsj0QX<{c2;kJC09&pdl2`_>RC+@J(xp?Sc~luZ{C@DS+(MtH~%~hwkU!R zOeJ%^c4b>|MpfUh5WVa;8jBsI-8+GZ!9;(+YuWAkYv??%7mu#sqy~)0SUicVaitTP zA2hKq;Y7{@H-JsC+HhL7E+QAfg;!^FIIl2d+s8wvAe{2*{(h(P-=wV~!J>6U3Bo{b zhwd#Bc5;qk^VnP&u2lMD*VXJnu9!D;2Q=&U)|cc@<0#0OXRgGG#>dFlb#@n4V)HR^ zxy+rv##KEUK(axDWr()arF&HS{%E8%`jS+1>r*H@*;Y-poDG3!EI;{h#)O?tjU#1& zW*`?TLM#U|WCTlW);s6yB9%b2y1$yYtCun)&9$c$UUHqY z%g;El$g7_+BrO7)rk7dfEV3&tkYwskc}gTk^ds@s1*na6DodC$tPzdnpZqYo!q&?K zm)*=Wgp`V#HIzVQp5k(W&|ILVi$)cc;yU#4dv2+A7iEpiFK7c@N64Kwc3(EGbbH+c zyN$&vw@BGCr0QlBASH`?>@5f|C{epMIJbngEHWV+xf#e3voXf57mXEanxu@C&La}|RmXGIC2@N4^JBZuPELKnQYZYTfUv_W9mm-4%`30mG zR!%SaIByT1Ve%fH{;aUGsLX@FYwj#M^H1qx(a3Ha8zo#0Jle>>i}x;}IR`Ls&+kD) zTNV|G_cary&31sEGx{4Spd`-w_ZI{Sq<+a~OTicF5qWrxZfH=A&_x5R@-B*P1kc@A zRuovmHJ3oJn&q6rfOWZXAQ!t+e=rAT=tzRVEBuQB;jUvRE47-vM>D#$f_ zd2EmD^zjwvN!1kvVU!d!D>tGl&J4^~gzpyGI6O(s@D=S1J@blZ0EwfJo-nriOmkpQ zqbAW^c+`T_Y>&@lrr0}s$~MnG_!K?KIGfD+PGTAudH^R)LdUlhMc8E~3LhCe>hNjxDA#+k6V zF8*`%K44yTjEu*D23{))sAx3q9@Gj;bx>>Jp?@DrDf4`UShmL@CX%&I+q6re>?mPLPc-wlCqP*zw=a#NbU^4=qh~iNcGe_Z8 zi&Omev~BXb^%ds$qTDQ5L%SVEH`t4_sTA&^V-&;$5po&TSNKbCp3~oz{)uMiu(TT6 zaV-1GkQL&m#vKc3no_StTK);*J>*e!ija_(2QH)LRE^Lg6>`?ljmAYA=uh^koiJug z@iKJz8xeO%z*UCZC>?QU=Q_hRf{^Jsa1j(?dZX0CTRC^J41<7M{BdN+{H=Yc#-Ewu z40>cHEaN;fa2S&})QsB0N)QsDNK3g?E|`;~04o-~iCm|BAt4?M3HNMk-|XXykik*= z<8&lo+eL5Wn@|D3xqcgUo+D_c!IM9*OoE0cZLI zmZ;uN0G=Vigb>?>2kB|x3Sb2>R!fSa$ z9KOd|^3l{};nul{(0tiSx*$=Xy&>`yyfMzH(KXm4Min9)lC$uS$q8ch2&|@16_)Yv zsv&f8kIGs34x^0WZr?guleD~M9iL#9zvk%+Oy{a+ad2fJ+rI`LqbtS9ZSs;xe&iqH z7hhl!5|o_qd@=SK-pLuRxt}LTbWed1eI)sTIaS!H_ZTN@)50>y)wsQ$Wcc;>ip-xt zPxwS7G9)Fzx0M+B&=E(^fQpgzql@;GytNVyU)Gh==^Bt6_3p2P$PV;T`p|s?rf8lE zIhFHc#3)O3_t}k~x6V@qFM1V49d3s<5lWT%o;L{h5Ky)1mzN#UXY3&Uj#H#~Lz8Xs zQfqn7WYBuCcpCBk3On|bERSy-LuYU+Wg5WeuKV?zJUI`l zxe5i(QJ9jeRap?a*ZYn*{4ad}I+uxY+S~+`G$Sdjy~UEqkE{MT`uVvtg~CM)sc2Uv z>{8ExSXHBt9~o42B7KBk0hH1K3oiW&d20EcW^zZWu@qM)5qGg&foh_1x|5X34Ri>x z6hJ+9A^`&+5r8MFXk~dIt1x$009$YOIGmf^<)f&hifGo-D((^`1Ve?S<@AN)=tpKo zZmH!WWC|DF$=4!^S|z48(rs6HzUxxNF=;b($_gtnzglAxm%>!&fh*|esJ>~kpJ_ri z<#j!m!~(f9%5JgjoMnx_ngo(N>zjU0fGZ_)iZyV1ope_15>Pq^p@pGMHFCs|ptVTc zsjbF3FnEj=_xPxsTFBdE1H}<@q~%3I zX1)J|4Y75P%`F@Wgk{KKc&Etx|aYb#ET!ILlalC1vznKaf2O z^p&xI5tu>{!=%h*rO4aW5gsrYdiYX7q+X#?l@w{+@Wwi32@Z03j@7MhJy@W2U1{8s zIn}^{`0yQA$c*dOS|K~-o?OqZczTv9FHZe%h}wc2SNpiAzB#?uBYBiPB7ol`nrQ&D z*Avyv{e21MDIs&TNesx)L-;LzA1?RCA9*QXj7zm~_vd@pu4kPyT#>Pfenu?omVQcO0AVxp@`(dyGsPW&XQT4?U^rG|=Xw*-v@=^|8KN*;37m1QiPlpG(IjKs5^p z!snD23%4{fge>$~bOGZ%D0H>Zo3lZVhrNvl9GOjyuz8sWT%mUr6+-$!wfyz%!42`P znl$lLmjcT=&&aGg5BdZ-*#pnCPmEh`@vcw~@=wF&i^i|SslSvgtg^j0H>egj$)-IC zS~d?^$9$zq(e+UWQ+&l7OOPzU)MoqDSaNTr&}O0*&w?2*xSAjS8Y*Esf~HL|DQS3r zw0N_Rs}4IEsgS%X8)8#b@k*-Dc)TnyGoooVe44sar^_ZUijT+lno3faRZO20BR{f8 z`A_uMLsKsK?w{v>HEq;+D$zHSXY^E1*sO^O!!0bQ{ISP(!7s16F2+q(>29h-GD3fx zCr$IgG}W7vQY-Lqf$pfK?cytqwLLA~I&Cj5Cb+2P>u653O(b=DoCkb(T>Y~myohH+ zBYQLlR!%w#vs}o?Kvw~Cx6Wu-fD9dCo*`q z8@>rYz}sUp3f_6)K=&gA7k&Q@v4ZE~ncw&$|J5`9)g%9g;w#U#tLPcH&!ZxJ_a$6! z)LyVR8CGvQU@!Y0cw3AH1qo+p)_FWlvDOSHi!l5bZTR%3tjOuy!E`=sp%e)v zyrQA7v*eUNxleO5xNyFR#XBNrZtiOs#q3m#20D-fw1Zp)pY~nAt6#DlvpN!5vJS1v z_qbF&N-2zY2?LL&(2t*`!{b4Z=ol0Ho@e~4hx`hj{Mlby@**g*JK)G1=BMb~EZToP z{DWgpjV|*@YLU!``LllGqK_BQ6s}k2^;Q+1LC#I;QZd{g(-gwt1&_p3P@HfE9b|9Q zm`xK9d*SW#gznd4D}~`6?x}>iOQU676LJxc7hhE5Ugirf$>AaThyHKw+5S1s z)Njt*@6ZB>B=bZnlmk5K0srKUKH!0d@q}x;=NWwR;Y#-vfIb5y=$Bd);wPa$em^xi zFTf{h zF;@BI!IjaflB~^ng|Kos>*G+uYdWw3IBSOiMwK1n0QRdBM*Kn~$Hp}FnA00+xzm&# z!#it|OGi|`l8Guq?};O~A@#lz??5SosD&yr+N~l>G=Fp-dU!& zvW1jkGlysl>JiJHd=sF7IOAA9uIvYzU8RMYLb}0QgtTpI!Cs2oPYfG`8^CAMUjHXp znYyCoA>{k#O;J*F+l)jd-h7S|gm*{rDu^ozaK>3y@=^{lQ<;7#_ZStOEG28)eVgf~ zbKxiv++K7B(KjLKc99bOKSvt%kZR0Z7)LW^Q)t-y3?mD|(9yzK1w+KH=wA9WVXt7I zN=*%36xhgORv1koJH*641FkF`bobxG$Uyb58v@F=8V*gF}0KVI1 zGy^!FJcP#OWgfh-69s(8nf)4l?>nM&?btPa(B&iXag67Q(sO8`4;w>|~A&a04`5NWCh|KJaCGMCgnT zU+m?M!5eYXs4YNmPuLy!wc-Inl@jlqG-3}Id!$Xbx5tBLhuoe-ey2_fg=ZrTYC)vx70M6wByD`)70(z%W4HFV*X%eTSMQV_b2S>)h@RMl(4=SD4QsX5 znbZgDA%+LQa<2&<^r!%ZOJLHUC1Y~HwPH+Sc{#xo%ZLmDo<5~ zhRV-Ag+(a{ba*C$yQOZH9avn^59&cUv!$Q5SwFQwJCV0o(GT*E4iWgfT$9sUB(2vQ z3twn`tg!`is2o;p;nMp%`4dR_6Y2H7##17`c-sLd`WXqRjrV=u&Y4#VOG2#S?|r|{ zZLWZZm_L>cq}C5Y4X*?VvxTELNgKd7N8bQ$$T=T5f@BWfz{X+iJ;kx#8|p_{dqL`b z;*qL6v5p>qN5Ck*0<3|`j5yMzKtCWIAr|2st+wEy=>K?#=q-hzHa}7}d#}Hijc1s; zsswG8qN)THO77Z?G@;-Piz`kw@8-vZ_JRGf=at!CD2qrXlc?mPtF}}D0T!N?GqG&L zBE+bUI53P8P`DD(1Z+cEZ|9Xx245Q0RUs-tRvEb}lq_Y@(Hax2VZ&=wlrn4X6Y^eYe7{}b*mi=;ySB5y&}yz$b>QE;sCYpLA42D=8$Zfc_u{mm)iZL19-tjt?Hc{Q@p^yG22 z2$54fC_C9j?a#~&IiF|89up^h) zIj!@IbNd(lgDb!SoM*DzTK%QaIu+b7zUZ79~qgb|W(>IfhS~OUZZa&pgum|U`6#%b>6JN=KAm2Ce zI5z0-w_vJjQlXxJ;oIoAW7~{L_63;jM3h>yVOoz8u8k~b z3e<9^$v3hE1ecoiT_S(cimCkPmLS8&RLP(5%AK@fYsJZOI z!1eZB6#~EpsS}tXR0=RixAR__x>kArMw#|N6Yo9r+sB&%UotHPu=+B^A&^E2`^|z; zPZ3{n(n(Wy90@DW@gNx;?v{8~%5_%CR5mpxwlo_;kdIajf=WKo`_oTo&q>-16iZ$_ zu=ECB0bO{W;36B>ZiuhQ2a;R)g6G2+;5xJ#{tBA66?r?AicqQtF#bt#)<-@9@9j7r z5KnI=Lxb?8SWq>vquB~Td*P=wi)VDLnc6N=hfQU+uZDQ)2lw(d+qRPxCo8sX+qP}nwpFp6 zlfAq9^xpmS)A#do%zxm+i-}rfqm|B|F=nJUS^-m>5jQz^DR%o8>dyM79Cf%tJ5Qy3 zRoNY-Z9x=}@EC%uNU-BPx>atqMEUUS2H|Gh2_)@vT-LsgRXH)M%u2p(9_1xK{>{MzTsRl&ymf4PbN z%dql=j`}y)LWC-;yT%u6VT)94_U>Y)-mM-~8C5mas=}Ah!eF_<&HgV8>xMC#$w=%P zt43=4zOfc$aHxQw5I8uvJs}lETDS0=_!kzM4(-nmdkP-s7iIUZE3ZzsG_sS4`mQaz z%jeG9r>r5TPT=FQ*F`5{w?_Sd_V_eCCk|5@Ta&{-a0{8@t~-nLPAY~n`M;6G9@w(l zfJsO!EaQ^-FRu~xfvpG)DJ**-#%f`4B?9La)7$ux190%_oZ!TAOr0XZme^caO!_w) zS;25lndJ9fd)V6w$G2ioV7bm%N3$jDr=>`fQtXD^%e?5A z3o!zcCoGYeX0syU4oMi==wh%pv1O1u3mO^8Qe%;3$Z~VNL~Tt{*9sdc)MG@2NJ4Jq zk%wI@%@-RjE{-oO%}=bIx6sJcB%vUh7Mbb3p`;-qfu%v=_l(02>0%^*7lozuJ zO!NXU#!@yYzskWihQ!k+^pDxbCx;33mcVcd-7bfIn_ll)N_w@}E!ALGz_Fn@ESuy} zvTG>_Jm1RqlxpYo`K4%=&)JNA9@Sx-$B`>uJ6@~iL%gd-MR0J~K>TtmfC;8{IAzB; zn$Zfec8ew5L1<*Ff2~2+>cvY8fQQ!r8#Tr&s-d~!>W_20X(i!A35*YlpHCF!psnvX z-nUq(wOHN_g2fpacf?D$YLP{RdZxt-+lgzsbx1etIG>*}>=>|T-jmY410-L%!@bkf z6IS-C`AA=@be=ETa!LPaf^_&9lbdvH$ZQG6*iSRE%<(&lIt#wn%_ov=PtnDoCjDy; z4BrSQ{Vwx_Gw6rKF9J7mU#daGsNGj1r>Rk0jgG6csXY|bb7SnP9mM)>mvObWZLQvFf9RmOHw+Q|{`E?9kQp-% zai`CM!NnGRTV*e({=(L_{rOaM4LZ=)ZUyp!$p=CDYM5BNDP2$ zDwCiTKa&WBQ+G0q5ppZ}&bD2r?QUG_8QSJuGbDPXb5g<n7u{=)bTJGjfe_#2n=PgkJ}aM zV5|EXadR7II3VUL^v(JzDy&4c?aPLn6(cyJMlr5G>W6FfT+=2h+$d#e9SahWVfs#t zLY~M!o;D*sqHvB?EVQ1K`bj6aAaoY){hf7Qzc$nv4YQ60hFVT+7Bd)bELi~wGh@=K z!Ezj`MCNSMtjU<_tqEQm=&&==+rQ6^g~mnc8{QT5?0Qf+*#?0kTujhi?2`z@ZL}9E z&Wuh|-Aw7{MOBPI+$a8b7)8j_QU*8mnJiRi~+OC7u@;N28)v|l0d8^iDus`~QLzc4mp^A;dH zU;osey=K(TS>$HS%p7YwiQleS`{P;oQV@u;&rUW%M6NI~a9{CPgJY=zP{yXPxbxPK zKDK4b9;q8;`{FsISryyDI!6kuZY5{8c->7wXK@Ql^O|+}qFk_PoQ168t&>GQ@1<08 z69KmsI~sKRH4Q};U53+1&V=T+(j`wq^UKX&yfx!&H6Jdi2}>zj8x6l#j!NpJ85KF( zDOc6~;gtTH@T?z)1SBePEb>{XnwWRjo)}9;ovIjbRVM1t6%aTP{Kc5iS~#ZL^US$Y z#iMEZQ(-VTz?e~6xqi$8UR1~;e$alnNa+?d&$CS?jU21N<98a|>i5L(Mp<#=J_d2& zGL&b$w~@1P9TtReNfGu0DUpZ2+T9 zRWS%v&g_UK_i<+q(vG3pxyR~Yuy-uc2ssQgbfh|QyTCE7(*55gH)`Zeb*?Wq9Fy7o z8e*1)iu=}Ld}BM~w&fhYjnL)iDH=>Z_uK}{vPvE<2x*gByn#&we;zYNhtWS?p24J) zh<(1!{yZL>R|pa{4^Vy7J3QFf0y4uap_Vz_oFX+OiU)%ft^!J#9eKh2^>Ts&DDGpLXre%=rJDAle^g34{9rf5wm=E18d5~X2 zCazUh_XoZ{ckMb}sROU~I>jKO1of~N+p~a^9#@c?=|b$tjt}Pn=(nU@My_E~3E5Um zOG2SjMdc;4Lqn8bxlt+jy2?SAm9REsv+Oun_CU!Cp+xM!mbN5UVfMod1Ky4wLADHJ z>>8g?NyXchCiGb1?kHRGD;%LgijxOYr3MfzTK+*Thq;|dT)rY9dfo{Sn4J@FI+NJX z2%Te1LzH<6v#YQ8Dw*4(w#nBV8&}RbF4y@OeWy#L^L`Ol@G?7qgiV5NtTwCEXVh2x z!Gjgf8zlw>8tp>9zvzDO>Um5ec>Y5Y0aZ4ro{=%hwC(4*Ay)~Jy}W}m7CTD&iQ*Yp z>dc`>5@pX+qnZ`W<4w&sAXz1;ftVjyo;*@2dlZ>83l8uOS{lMh%-?42!?-Fv3niMd z&tqW^u6o(E4L88GjXG#XcT{|~4q;`wt<>aak(OEX+_95vxv+Risa6@WGY5Nuc9FAFs@1_Pf% zk@&6I?ZW zcQ8ZgDzIb?S3OHZedV>~G5_@>-4OHd_~n1~LRtT} zFF!!V!(G7y&C@FFj_jm>4=pZH~1=G-N3cI>4fh^>?r=8a|y0=TXP7K({kQ5eic zgrGQB0kc7IEr3*~g$Tl+e$bwbY)9#%cSrM6R!p?tzVQnuq?}s_7P)n%SZ(GMw6uRv|=%h#wPb2r0Ycz(n-Og7bsq(cxWex|nQ{ zg>=^PnJn!3EQ&EPQlt7~o+5`@R2LSvc4S{B8CB=Z}^DCo9hw&NNxRvuz1R;aG znfn?+WkEj!hw`brY)lpiDta9O+xJ*2Hs*OOn?BM!b2xT6;=BNeQF^T*VhC!wWPHsa zSGk&>Losj{l#wf}*l^CWrF$>9FvU-9)4{GW&RHO!b3b`^idz_dubU5Y`gI@~H@4HD z!w9$fU009Kg&~;Jrw>mQh6ew%=&olqDW)&;6a!(5C$lr6IxPwoz1vWnk0F~FFHeQD zTn{<(bn)11l;`tN0u*wbx}EW@8}bE(*~62QJtPO=<2PzsKS)%bfDwNZK2r5iY@wQp@VAA^mO31 zC1YoXNtTOv9;y`YWA(xdf zjhBh@@|k`GHfA^BUpIm53YzH}M~Bxz7CdaTwMy4wHNvwWPy*QKzo2{`*@>!`@`OKx z;QQ(MA4IEE@g&6?asIB=O4S1C@o^G@+2|;nOa1)Qvo@dwX_)Y3B2|rbq}eD!?jPg6 zUb=sZiuH#hsM^<4NSZrXs_?E;+c5xu;Lbuvm)%A7>td18lLnc&Nj^? z?L&uN-F_WU;gN1+!`KCjiEA`>i5BjuP)+OtF^KKtle^iEv)-Cc-stF1E;PNweQfVb063k5ag33cXr_>MzlxfiMq32;a7MQ0 zjJq{+ZQ0x68|-r#sxsSnmia@KWIB`aiu+n$SU;An_N5oUZ?2Z^F8xdVI1w|PxmI9dE%rm68%Dxs5ai|SQB{H z!A+?gP}}`ljoOf@npAF(RiK1MVQqmx=P zO8xvWg+^Q;fhNI6G50%Vpf#TY2;ql2Avd@W^WGpo-`g{v)n3ZE$~WQ^)INfONOvvZ zP&K2D3Y|khWwyjJajS9+gF=S-vtp*gJ9vhA1PeF<-S8Lu$~R~Uy+z4kOB~Zf)%5AczO8iEc>?QlmnM-PJdW3%VarLCi6fKB@yX z`)lXs6jtn6z2r9`*MxDOvIq?8So+P^VqhhrsMcAzPh$Kr#&yF>^i_rJk3ab-{iFKU z_Su8(HDpL;_wP75B2fdIoHH<_DT*P+oJ}~Wf%7MMnw-L21P5;nntnsib*In)#sL-F ze#Uax5#h+ysEb0Pc8cS-Xye-yGZT6q7slurRK;&K88Cs&v)@g1=$BFHYfUG2Qt9fv}jU8q8__R%5fy*qHD zzsFCYEJNEjzh{*!g31y$u-w@&+5ecx)H3l3n8+}I8MHgf!_5L7e3_^NO;%K}Zc}MP=>iX)5k)2uR&=qHGGJT;Y%UKgx2nGjfc@2t-WkMenfK5Hx6n z8-xFT7f3g$Hi(qFvrRwnlbDe(IY-INa`z z5v7bGHgLqh)1C;3Y_sbHz3fUgT=+%l9{z6chI_l=2iNBCOERir4cNlN|CF%=|FF5j zJdMm_?syTIvB5MtImtqd(wT%<63OnC0Q>l*9YTjP{7ZG1+%L=8@1VI~`;!W1p45J~ zAzl1L9MT$MEvdPJa!6cm_l1B8Z&KWYY^E!wWCVAULBg@>;R##bc`m7UtJVnc7`BA9 z$ENCQeTaEySbHF5A`vIj8$XLH??hUy%CRAYy+a=0C8|+tl0o^VV0E3qU%P67TS`b* z*aW?UH{NH&+U~`W@Hq)!4Fjrw{n06!{MNsYFW>$d*sCrOi*kVe_H7^eUr%lSN9^oB zk+c7Lc2m+&KrzAe|C*eLa zpGa{ANtvhvV58T@15kS>70)af+M>-&t7(>WOiNT|Ql|knhfiWeL$%t&$4Y@)nZGDL z(Fq|y@;(vCv|&Sk1*l17!DhZ#G`O)F-@aRi?w?4oDg?qHvZGsrjNXAm+cX42I^@vX z1eWR=%k;fQuFBMWnQR)}2bbn|BhIO*NKqhyPX&B<9_cSAxU+8QR@Lf0X!8;D<1?{T z_!P}!6oBv$t-ZOkwC+-!Dds;~cxQoTG)_-Y~GO~EtcsvZyu znU9q5nzK_>H+^uNYXh;46tt&*%*^=b`y9=X?L1%y3naCvz*z)V5=ou?Wh~Ak0F^%g zr+i8Ufv>>U#yD0d$Us3WQmlVh#zhwme`y@ZC;zTw9I}8c=4_RF_N>Qm@&`Z0I11)$ znPQe{_L>3I+82aTQ5&;|^0d@$L>zPoK71Pt6p%1>M_64%{%Ze0qKQ?)V63aDENOnc zfNx~kZn+)bj|5!*g`Z?I106iNo~@udB`o$mME++raBqG_QcVv{%?diqeUi9n2RF=~ z1Rm5yvPzHYcF?eD@z(W~BaVSE1;fy6#RXM!KtrI^=e)5BDZCtKwNr6iIw4nY!J zd)Ombs#2DCHE<-wxOl3^(sn$rIHy`&t@I8yQ=|BaM}sNDDe(-T{DtCCf%=qOWUgzu zo*4W&pu%E>dx?CT}n8T zuF*<378!l%In2>#iR3ic&5=0i+j6JjSC5Io%htKP)}Dnrz3qR9v-PlXEp*;}Yh@w1xt0343<_YZ^ra%ozB`~yA-@)(Y zq(>ViO78)y5DkyR(Z$Uv-2WlN-9LX}G|rrUda9S~^Sd(rtQ>kVqdx%vc;ccJEHvPn zqU!6iqdT}YOn5;ciPbC*4J*Oiv%vtpSq~X|)KjX_ec&1VXbX1QJr#&|ExWobe;YYC z+)Loyw~Lzfa8ma4@?Tjoa({w7XQd4Hlf-7PV$NL^*UZS@5YmJUrVgPbyP-BJ93~u+ zGr8fc3zXp5wexl&*fG%m^e;t zah+4vZTgbi6e8*!L-?Y^=J?A3zw~jhDU^ww@*jVq#tN2tEQPvJrn0m( z{zufWH+W9dN-MS1LP|`Cj?f+HOd^F-9t}!lZD#7ewto7=<5;pVxR`n^Y?i^i; zP*2=lOyTexULxoq#XjU;_Zd<bS@|Jhf%WaYOOu&U274A+3E83! zq2ZFq#L7Ry0gW?0*ztS&;2_6(C6@3+RJD7Skvbm>DDZm>VDJkl9#RgHyZ7J(QY&GX zWI9zmJALACeBO zN!wgQE!CsHp|!VFyP5E=xcWx$cP@!sb}<_hLWu*8P&M<--gSCyp_59$Y6BaU&?`j< zGq{FWu_DR8OK9cJL!rkg+XPU}#&z2|Tw0;un=Rh>&rM6F^sq$!-KnP)r5~&LiDNPk zD5^G1v>dvk;*>A7qc$kWtDSzGWc}$Bu}8Ykp;@{BJ=%Ne*#(qr(_}S;QFM)4q=%uP zQZ->;^&`Rdm3P6anr7c;8jz$F5IQlEL{<=3)~$uq?!$r6Her7ttirY4r7=_F$C?d+ z#8%`KNPEQX?Gw$}U1mFgnqj6|UY8*3@04d7kF^Pu)yJH|P+nTB{k24Hmts#QQ6g!v zGAW3P-MBxW_`Z2@lSC~Z*i#chwZK=l;4ic&9Z=GfC`Q^=zxJUp+m8?go^~-%2b$B~ zXO$3NzPW}Q2}hx?s?qp8Dp4RPX=Oo3$`M;2Yq_9!0iSUd7xE^vP$j8B-EBhf)^THI zfJMNwpFaYqema*qtlA1_L+z`*qH+w`<6emYtt|SD3NodhXfs=Q*xFlw#@{3|^-YzU ztSKwq&^7Sn0ZaI}o^J~|L|V!VfyV(6^718J&PzfxWc~xfmcy1q;*NgM{S8Xr2aQ#{ zk@Rt|WU5;O6H%MI9zD~Pq-p3%(MEE;@|2*Fegi#x$KHm+;KzG87v$Dan)3rJ*VHus zA;N%&E(#r3Ee7xNQ50uz2~D|YsQcTXJxbN=^Dk4j-52iQPinxz0w;gr5A@B)v7tBJ<43xGNXXlw=TXOBAwUYq|7%$M zOV0PdhQ!&hKjGsw6B}e;)43$&V);^3%5ElIbP4M@s3N{qfEEN zuNWYA=IfR~)Q=fBhh^e{`6likX|1l;r3sFCc%)5dtnkMikZjf%KL_=cde< z2s>a-j!GR&zGBwQhf&~pHM$1zfa(;spyAwoxW)Uh=JG}Vycuk`uY6z`%ASIXF-^48 z$DowN47^BV7AhQguST1NdUC_JG>Ce=B)qXzHZtH=Xr+0zgJ>Bqw#Hf1bH+(PjHpdm zmxGc`-9-OFvrZZBtc8dHZJCejYxwHJ1dd>LhtaQQF)l=>Bz+3h%~dnV)N{U7`_7IE zOSxt(!Of{1rvP5elbzUKwdme+#L);=4?}0Ex~6l)yrN(RYbh{mvshKub?4ty!?v@# zOGT?ETEx1-k61jb4Fb+AYXZU&e-kI|h$>MSi}3YllxtDM5qUMmC6HHj|E!E>Ss7|b zU$DIIktK;-R0=bvlF?9VXs@-pr?P3J!1aCi*EfHwICrES;k`G7E;kc!Q;5SWLCmB~ zQ-5oAP?!rjcjUyEn3HT_z%{do5aGG71C+0`( zLlW;aCeUNss0Z*m+j~WOqcyF`%FMDJu{1&m^enp1l5T?iW z5UYA9&LMMv=$kegGT|h0NJnd++tDYL? zx^;W6pGA8#2SUo+)Cbogv=Bt`XUBai1V_glGn#_j1=3>{9E%zDzT|2u1ZRh_6iIb> zx|et$D*#(eNPAUMFD$!ilhS)2s*sffbo0B<0^2-?c;INM5&69QZnWhRGno)8p}-nT z0!N$)0Q>T;vjC7vQUPSfI}gt&I$=*G@31ycy$sjN9?5k-@eok}ap}0zddU>RFagVc zIiE@HP@5y|)$v-|@$Wh4SzOdrboA1hV{chCvJVhS>RVwXtvC^14S*fnm~}U#uqX>6 zBoVAyoDZx2(IGr%wF+7XC#=#d(}Xip-f+y(Z5}#Rx~SZSB??XDc+e=^CdI{)W#yev zs7eVfEWy8{8uIk|K&joDXoc+X84S>MI&2xt)kqe0H%h;mov=^)(SmoOq|9O)LGKk* z*f~Fy+m7Yx^$@diJumSn=XbVTRl;^(bKG-=w_-ae0h!Lk z!2+L?L%bl6ijSOtV1>R7J?I;)1>ruN8^rRSj1PjK8#5*(gqLfhI-9Zm7q@*Z;ma&?e1V>w^*-V-!k4F&gK1y()sgD^^ROuWobHE#>;2@ zPi21xP;43=QTv5t<7ati2>^ZKVRr3~E$m}dalL~R@WS~Hs(XeAmaah$PxY4;Q%W;V z=Cd~^mMww(S>#6c_vKb;mbIL6c0|aA$MU8YC!`%b(;N@0^7uPy*3jh;h+}PNVT>_tRX`wxB^AcI$F!CxRGE6G-)*W zeawvTwF8aB=avkd(T;u-nx!u3d8jzl%hZWVU+G{6<%wx7CJ(e&JrlI4LjxKf2-f)u)PRca`r)%Xm#Q^v6Y+bRobo$M8kyrl!~pC@ zIdMsVcDpwQK%07|&YC_Hmm3|ri35mEXR9@2J9RuC4xm%Hk)Ke4zMD$cZ0MMv-8O1p z-^DJx!4HXdTq$Tt{HvQ*$e*Hl`?>skDGXF*zFnTZwl{{49!#-!nd*zRCPkrC?;Lv= z*Ak^@5Q+Ykf7Q8BpD4nd+rY2a*oo|zMaDJ^L!gt@gStnb@0yJq%`@{4K>VAcLBU;B zBh@TudMG>r(wO0IB1VrKp`=e)n|Mw8?H+S!f@8fd#Sguy+oa30;V^=XE^eLbm+RJe zMJk&Ffbh8;_(w+VzTXTM&^l(DBmUnD$p~ZRmi%Kb#~}%lt`kz7u9c)KlnETiySmIvVuh25Fb@!2ng*8ge+;Hfw+B@@ zuvf4sSuA^7<1oz#Mf$WzT+uUQ_d@+*`Bx8y@|c2+GHuiVDaO zL)~;&z3r2)a`w$BtcH3(nux-7x4yQnA*x9J#f3Dqmzwp%HrN(2am8`1S2<2+Ur0;q zequI$K&A~~`29%!a@v1ehJ|-*cp$7dXI^j@51X*IyzsT7+Au^&0=&vA=h>yl98tgf zE4rG3D6tg}%^VwiTgCjD>SZ83aCUd5Ai*dzK}@KG`-z@5x0Js&e#zWL%zqOo5TZxu znN4$zT%We)?P6a@Lhv*i*YSq>DR!F$o&(9UR%u*ogB^L_ddT)9MZQ%6(}R<3wbq4| zD%v8y+MM&+c-VEbg=>K^3ARR_DZg{zb=5`vQKTVnXf^+a@QK49LtU`Ad1?X5o+a_|69bKsx@BT`vxrWKbealQSW0dz0DUUK0~-*d5w^kUN%Frg1c z1St#DBNX;>;&my^BtW=w&eHt#T4u~kCCfr$GY-IeeShc9*j12)2*b`XhkC18$GTKC zzrnE4;HccfGlN|26V4M<8+`q|C$ zEUAGx&EMl1)E7c*;Ugcaaj$Zu=gkVHagznd?hpz2Z4wH15PDeDGk$`F<%Tp=Zj89u z#;E%#n-8EUz-sCn`;`9hs*wHLz@aoum?V1O#c12A`~mh(%O3|Gp$?9GQOo!)5H86I zSfGvrttJ0@?sk_gi(rhJ#+B%hk4ureQ8+%pnAbNPrz%%U^A)`j8kb(=`;3Dq%U{{e1AD8m7Dko&aQhZ5lbOtN&_yy)^{ZWej(g3zGBBj39*` znLGF>!u$blYFC^1;2r)fCM(QOk{h`|d zO=Ko3)f8qsmQw@j<+BIl3y^=cN8oj`aBy9rtoVr3s`KxtXm93?ta;+qb*qqd!$2!X@$& zQKui=Dh_4?%nI~IRmF+KL^X!4rEd16oFoewDW{YCx_=M5D+vNoaEyyuhwP`$R_8+v zkPOB;cV7|u6$z}Om{*I__a%(6Gbn4tI_U%X9sAvrY7g$slGwg8r|QbmH$XEh@}TCZ zP!KRnYVc{#JrG;2Zq5(Ydz54WUiYGk`8%(Y9kT%m?i&nKe(R3a0N8_y7KXoihbdtG zlAOJkBCW3?EtVl`k&bH&R-B8L5?ZZ$>yBLNg7Qo%fhJj;+R}0KJS*WcJzI(#qgN~u zg=r6_b(MTPQ7QLKQf2!C)qp75HG>VuNC50UNvaFaWIfuA7}U9{=%ur|Hwwls0AKxC zMRC}+lwDK;QPy%2MBS$=;dT5%>FM0Sz8W)jQ^3Q8yn>aDqLCxF=+w|+BOs*Z9bWz-Lg-i5y+l(s##y%IaiYU? zN@qI4>W(bC#>){*Kt`t+o_%LkyB}@;U>L`-ypBt{=kyEc&RGR>O8x{xp|IjedEvLR~=}ev}?BCLylW_xRbrCrYPRsYA?5I5Zy5$(T%fT zKoPkH$H@tT>!8Zh*`F6R$d2H@AJ|@9Xn+Guz`4KCj}38r(IRhb!VU#JKTlN^6bo{g zHq)TMDgVUDKxs#LG>;(V>4WG~TJ<4}Xq}0k(KS<)4Qb2zq{dl1dxQ5iT`}Zfj>U0`kQIj{Gby0>+;=Bb`)V>`1rxLL8lnK)$X?qfZ z+{ILcv)zWgeZF`37SiSH`?}LxvDT7Yjx}mzUqTb2plt_!|vIL5rRXR5k~HoMy-_0+zAW>0+@nY3s4ucLj0k%(L9 zx*LeY^P^Mts^*v%(I)(jG>R#vF{bIdw3nA|t()L{i%mZZ_qe@wGK1nTbZY+3#u?qG zE}{S@B*YKUa4$sHmv5MFL^k&%x+h27?R2Kl9+aPLK8s9oS-|3uTM8)1;BM_kTab)C z?bcAY8J6jz`{><_^(+pTZ`|XcC%^F}yS9mhQEsIqT{jo}A%TD4Myo`O8}Kvv@QdQgV<5c2U|v_yboVc%MD#qaaR$-Qg#O?mU8s6A(TBRB z{JB=o4z?Ao+l*4XjBx}H1hO<~Eo&43IFoSY^k>Hum zHZd8{90s)9uIaY>LG^Hk(-`FXEWV4Inb9V*I()X?x4tQxuHie7(e4mQiW;bD%QL6) zJy@nB8(mj~D;35W?tZ6+Ia&fhAC(uQDU7lVX+Tp1;7T~Wm8(6z{i{F->})FfH3K zV_ljb@3$cS9Zg(Uz4R();q8@^!RJ$KdK)}^P@%UxEw*X-eladB81AH<>*e=)eZ-K* zi)De`t)}hEhj&G{T-|qrEja+yz5*J zV`|$e&6%#(R8)s7%<(e0SniB8`w*r34T=Lr-BXJ*!aVT!b{q}25Krm`smzlO1#;mm zGB+}sinsF8RdmOSVO5X(=;Tg9YUr9t&P(!E-%JoED80h7)Gu^}yimg64m~L-7%3;G z*qMMCIs7I))gAkNA6X3NM_D+Mr;t>1)JgDk7X>^AQMVFp6X!b88!pg{Uq!K)?mr;9 zkRZB30)f9G0^Aa9lMC%|CU%*Q*&}mim-!vq6O^x6&9=|!U+RiuoMf58of@EBe4l8< z1gvdiIuMKBGIdyNDU)>ec$;V1*jzfZYtVV`vET{Fa$V3vR2xklznk`Z;RoG(G}8kJ zy(oKbHEciHvMaqox!fGBpvw>7=m_H$_T7QYk4 zn64|OR@DuBIyGSh%rtO2pYFgzERX9ATwZ6ao)Ecm&(ghIzV7SdnS=ET+;V?1$}yl zs8r+r8Un@spr~KG`GsMKZVxTKYCI)emBuo5LX4CeKaXTa+Y5&@f#LnaA1E%*Q{L-c z(}bRQ!Z#37him|{ub!BvDnQ7M?MNA3Q6w5>;_SGl6e-9`O4~X(sbSKtok{mp9U4w| zzVnUjR7JPbdXO|v$^@|?W%9iNk4_E=O=8@ zz9=Yw)*p^oC0Ee#R_w*Aa-as=<14;JQoeQq>HMl5zf{xz(#aoX<6H4B8eh$$j^KpN zyU4p(3VJ%qdf=GTGP5wL$CZu56Rb4pP??JD7Wg}wm5_;WVHB);wzgBqk$@=X6=zZ9 z_?R(AC>xmiVoOLUQZ5wR&X*6)A+Y#NsuPf4aQ z4^05mu6|RF4-XnkwivL)?uM(CdWlbLo`Bvv*_-AkDVnUwyxc zb&N65RtgE$IT7v`F%Xs>PvBxoGi9l)rjDps2h+Hz>4GhBJ&REyamROI+b3f_T~)lm zQDHMoxGqI^Uy{>tAb#^ST9qS-6~W6z(S%MvFuntlVqGY*Eyg3tvJpW`8}^?XbEPX< z$s0M8#Zl#bv`+mTN#=XyTf8>cB_^MNa$ua0hX?GYr7=h4Eu5Rt*><@*1hvi?8K%1_ z{0SF@@wpw}P6@%VUA9YVUE5&fk#ghm)LG251h`$CJS3|=FqjlswluvOkQouwkyuW7 zY~a_?ye4M=G%hYbk^w72>1mBeAPsabaO6=fS3c!55_64bmk-JIaZV3s;%h)Y?&S#v z&Wn*%JD1f&1T?3n_|_^7?&7*yERA&cic-a*XYOJItXsLenw5Z?m|qJ5uz~+!JTjyp zt-8hj_DzrVKUA}?M)xnV{eK#dz9hAO;)M(hzN9u#u>ZXj`wI~EUmqy|ENv`|6a{4e zLtBfGTeF(uLrtG(fSwFshWD`(^Wi_`p8&Nk`L0AID50oiCpwV#ms&5R4acGg>H{Xk zw;zZ>-9#Y@(RIkh5Ht1V z?%*T4Xg?V;M>bYDr;00Zy)v5kjIq4&6?*jW4`1};Vl>g50*SUDHaMu-J|>k1(eupN zS^O*L(fl4jW>?!Y_9 z?P8xVaGlqQB2w~IR)@1}U;7fg52j@GEkiNiK~#@&MdiDKa4SNl0zio520$SyzJ#r`GvIw;Lu_VKe*~g5f1`^1A-1=_j@$#5rCy>yIR4 zff;3{t%E6lE2=3SLy^3iKQAZ4B7w?x^UQ~UC81DHLK7>mfl+ci!cb=Pyg3-6vSz_D z;c#Cc`Tkgelu}fj1v+xgp!{yr%CrO6`Ed?x4Aa^A4{){*#-(8pyGLU5Dq0-G0rGwAnuDFaM~|h$MPuk%GfGQGm{jRT7{{f^8Tr0o zo&=H`-nkfmhIY0U(!$_(2Y|GeZ-^zaCw-SMj|*nVxgg`B^*@B%KA3_Xs;}bu{x322 zAFJ(uUy^YDx!P?0i4_3;AM5hx|M*hM2nf_OF%q=1wvjiob@+mT|EB`1w55Qfg!*CS zNs}+}9K$cs5RfPyr!`Bl_+>H`IhVWIc|N#HT#^y<&FP%}L< zbG_0vV$1b-A)N}bibY=6_L%NA<B`F<|*jqO_2Cu+y8?eJ%+@V&%EJ+jcI z8CIKnPh+b2n{8SXE;vZw^#v1F+0L@EhfpdU=xfD>(45t8qYvj5eO(ub1b6VfJ(vv! zoI+qy4?%<_BN(G{M9@x9X)faXJ9`)rxF6ihuQ^S(5p`ZuJG4GbJ$9Ax#Icfsv&mj{ zfRPDJTWbtW6;nU#Cny!xS6!E4xPJJbnzPgu`qNm8N&+|x#qd4iKAQ%%=+FrUIP`G{ z9ji-~<_;^x(|tTjRi(U6z;a>DQMHCHG35Y@SLOAOc&&H@(TX zLUa%&Jcr}`gJroG<;=AHSFYm9o)S6M8Zw=rm=MSSy|SEgwXptUrb105d>~IOhXR{A z7<$NH>vVpc-D|~YW^x~jizv#NOTT5H&5GHYQl}}5)sYOsE;8~U6e!>IeADLdNHkA`T+^bBDc{?W0pr}~L?H_-?W8kB9Lc1i zC`H7n7haJkCetihF=5VhPc+{CxiPr@tu3ic#Gd*-ir`4MLFWM z79cnmCXt=ko@hzY00OIEHLicis8P1^lAmdba}Z*pEkX$GZWW2IwTV*{LfV};zOdsl zq@mBpXo9Fw!!)xK122nlZZA&b8@z*%;98=$xFaO%C}Yh{T>LKpAMS+oO8K^0RB}7* zcm?JB996ObiFiPOqe@AQ(TJWrW5xsfo!mHbjY0jTz*o-H<7`n&2`VncY0BUMG9ofq z3h;sg1{##=8Gb3XDUE_*Mh9^>2DP_;^PK$8-IM5l44^*-=2q5D z7Dk39Mwb7A>N{6KHA4M_r=~6!pbdsG0{|N7sMN4$LZSSjX|uhPWml^?x4UcWE+%tT zSDHAA5Iu^ekB)1GrLbri3N%^@ANmznxzc9iP+saY8{e)dO{q7h0fiOiDICN~ z;0>CP_e?I_8Pl&fa|W);KL3xhe+sfSV3I)5wvFAkZQHhO+wR@AZQHhO8@sLDw!2UN zn24GG-kB5UaYd|%_3*8)Dl021bD=OV<4L5O)arO~JijU)gR#T~)GGCCP;+JOv>Km2 z1rKkvF>u6#vXV(j)r-|?%DlWks)p>WKtv+==rOI*&yQrK9%5sLB|!(wowHjf(x zS9SNCInfi~s7ys6(5s>z%<8jD4S`0&Xp_;#oVBo0J@heZ?T?3g|IEwxO%$lReqjXc zT3Mf+X`-m6l!W#6vb=q5#QTr)vQ!&RdaLaMDH~b5(8iAwQ%76+oFb#t5>DYPr_CWc zjc;maBm+x+&V0;`y&w2$#3G)eg1=;bh>9?R%3RzM@>Hr&As3IWX}aN{G*uY{q#mfs z6Y6vNP{Pfc8tVpP-=O^9U2DsaO%PGeM3gjjv3`^6$i-F(cIeQe)D8WbO8@IzY! zrIx3lNHfi)5@KEPC#CB80w5|SWqMGNsRebdK;+4TB?cK=Gjhjrjx;7vHfjFELnHb5 zaAxwOX6`-nyC6?Mk0lq4=JFOJ%UCP$)oY;OLX^IQkN~QE z-+HCa*}&jF<{&6QB}F6b@2CZ-5^l=E0T3x~WZ>x!CtwQBIxV9wI|DBV|cE96mIh$`wq9Df81Dun-W~qn*7}&HoYd#*cFxOJ&$N=r$80VF2>0=d4#eLNVY9P#WC`hV#MtH;gNb2uUHTl8=g($S)HlJ(t3u&iCtsiExF04u*e8GJItxiOh!;xPt}4 zJ+hk$lv8#jDT~q4=s#r9T{~HUtu~@%Upufh}BsIr{U`B?BP2`8{}!S~`q+rq}CIAXd(XFJDVk49omgky8}o z&Ni|=S>?`-^=u4l*XWYXWs|H!w^xVp1hQ}e_LxK-i(`vZWs8e^XjcXrV*nqkBa35Y zi);P)g=esZW3W3opFcE!!Y+Q?(+=jN9S2jD{&e(?`=mMHVj}Nb1C94{L2F&aE!5%l zB=s&5)=onn#I?i8R!G0`tjq_}^$`g{{+z7t0)L%;#`RkB38FiFOzu;Py^LDtTW$Gd z2j5%FAL7{GsKxjCOK7N@qzO)>o2kfu3HIielJ6&4+$&;o>;*kr6MKT9_Oy#XkWNXJ zk>^HE9l#Lec*v2@Z_0au9^ia@AB()^6qU1}HT|-r0i_Y8QJvc;YesESwXAMA&K%s| z#oY~seMwloLoFQ!+VhFl+!`VE9z^k$a@?uM?HRTG=p*q_;y$kW$NY2w3e4c%j=~UF4?7})}mM$%au>58DXt(s5zZCYnDL0kmo?ACg zWKa(->S5o1hQ1-8e` zB_~HN(-YUA;o#vgQx8rd&~iPOpvu%!-u-nm{g>@ACCXN|6-IUjQ$i~5!+S$o>k_DD zq(lMGO^wy0%)Y@OQA zSIDK5t59btH&&IUJXzBgE&WWG*`!u1(*%jqqGbMc_fkJL9dbjcFe)If{a@RKo;7JU z)6j6mOICGyhIqT>8(<)Gv*^c7EJA5v5rganyU{X-*w=_u+4FN@q<}0Y;=JL*S@mGX z@3_lzQAWxf?^a$ul$tjs0mxW2Y(46AQ68{l4iRUkuU$Q9Q^&tRfueykBlBqPpitMn z<|7)RW+1S)@0#Fk+!M1{x`JChgmnVz)!V2LF`{H1z>MMI zPaFjJ$B&gPlxEkGF%@oN_yq68r9g8f-!tzT()93(?v={XeA^s;X^}71Ayb_ z>wp^8RiJ*n6WjGkeG+X6+>5npL&BV$Ks(=19~!%)E(6Con7pWrib|qA28}Hq2`Fp% zNbO4GR#Jx07wqRp!a&0j(b&}^5SdC`A_?>cFkQo9E!&8@d2av23!C34O82ABwxAI5 zHtH8Qv`V9<;;g8#bW!dUzkGIO&tGhp|y zBgK%R)cw(=3J%8%4&b#3x?A6>b1>>Bk8_?N;3*`aiEoN`cXua5xr!MYAOLj&aw&!& z0wuy@EMeDGq%>719T1ika9u>%lt;z1#g{t-f+ps%tD`w_nrf=AwNUPG`Ymwv-iAj= zvJy!hCLX4iKs5vZ{T&6Ts$o0h$XP2WSG=&GH7h(t(SYQ0L3}Qv{AAFdFsC8`E}U_6 zav28oRJXCe9_+nvD!ZxVG)T`)ixuM`tls!q6QxUzo|VI;_ZI+rm)lvucT3xW@V@+} zI#^NO7P_kM9u>_*{*}5lIkY}oZki!)OW;fdlrnNgLoh`F7phJ6a%h`NN`4D|&o%p* zP5>4phsXbVp3-t8Oy@n!l@_aWfYcG27wq{U2&ZtRUx4RH{*4{*b8V9R{UWR;0`8Wr z1)A%{YIrwtYUnXy7ww6*AM2)e^r<$_!0BcYW`086>|*yFC(F>j-4h2K!z5aC9SpOg zsDB4FR8)gSPBefUZQk!360R9Mi3}pk1>75#ViK5FMlyEiM9SxqqZG`$$8%Yw_RcYU8cr^y5RM1{&j^m0e>BLExJB)T>@ zMvDNFvYyV!80VNtfOdX^8OFgm{%QpNYP$gG8>jdLSb9N+EyiMu=P0GAjSK0<2MuMW z)g+!#Py5O}dhjt?=sN{G-07~r%fO(7#yFsQC_Uy}G|_24MNA9y>4~LZB{~xNkP3`J zfDvUhyBDqhCi*ZBT;)5qQ0^X73VjTC(_6s(k(4Iyu#0z~g!d@LJuum@T-pF#+K8R? zCm($%UwprwwSfoOpmBeuM(^6ma3oFPu*_D$!`v6E3$5d4HpwGyWCdLBzE91>_`8{R zUvlWh@1am(g-bkM%S~FD#Q`a^fzp5%=9nqA@NE4NbDsO3#u^K>IwA55ElC_lc z+Hmre<$JC@#oG-P&-HRsN1OZd8=TsD?s@K>eeas}sr~xgL(>B^?@#ha@>gjmX!RJ7 z#BSKOcG|+N-#RqtByt#&z>`=PB6@1OYy)HV&oCUVX*w`nDBrduuOm*L>F{~7;@Ff} zyWM)p%N~bP9vZ0{RCSt>DakMzuiB(VxR8orPsyBI1FAfcv73lhN?}^ScG314nrX5- z&HxBBE1a>{%wxSykY;nkb-9d@9^u@`bRu)K&CRT@cHn$xBgro6)aXO2xkj7oSP*ih z@Fr(d09)iQ?qm995T&4$#|`374#$@aEE`b-mV;*IX81lij(Wn*u9I2P$6y%Za)o3b z{)$b$EZ(wj4>!B1@{6B=A;F<4ZU~o@cOg~PFXlHf{1OC2L?w?U!KnrCs_I9njx;(8 zO8(o*D8ca*mBE!UH39VjKTKBc>7Liv)0_03Iw>|J42(Jc7?+LTT_ia(OV<+Axe^4& zC*W>xg35HTMREy|1mg^~#AkYT5Uj5c9Q-tIj7+^|3S|^l`3eWS!5>yUXdx$5I;2Iq_UC(=Ie(HTF35^$73}L zIoUf2k5yJC;te^@Ar}&i!nUekZimDn9Xk~EhB%ABM~w@0TK&Q$M)-amuWw?`}YvBIC3=LFv2mQA0#Ky2h*-cbS_k{9*y?aFw z>pY`*(f!pPEfVilw)Pt<(#}BQ&?%_oHd?E!yL_c~--&^lSMSgXcw*h#vJP=}-td@6 zpC#u+OH}Vb#O|)z+smk})Dx{T1hn@hEe*2=S@~tfan$4z(q4qH{sr-?Ipa2o)4% z#q^ya=wURbm$n=6vYft(WrvVgvhYb;@p56v(1P^EiqwHaaB(PtXVS54K0v#GH3&B} zAF7LO>;cwpiQ*MEqKkd<4)e4(>Yl!_E$ahEKA}6FD4%yhIhxP_z^hD1zGr)K`?K?O zm~D*ejtO(k3%z|>IKYQqk4=8SCQ0%6V2m^L&^uNGc<)9!DFj8o{PF2D;1(X^U*fOy z_ixr3g87TcjL%M)2Krll033ohk2=V@Gly9gDRRawx%LUJ2QBskP)dAl4&_HOMC$WF z?M)(j`Y7%RscEwjS|7y3c+W|aS0Q+;B5pXPBnl;mUP)07rmr_udma;OBvMH*`)cCSvT^^)6 zu|b39XM%#tB5wW&pdOuR%Ez?GwM9%>w?p#AX^ zghY~%kvSk^Gu#hxWL2-a&&j#7xx=K%mDf-bv1yos#yC9nNk{~rsdmHEra6R7-4VA| zAqF@TA1syr+hIL|r|W;!iJLwm2K(_Y42O9o^bpo&zG%$)Tcs^y|H2v(9$(A7OF<_6 zjs(j_#K_2?M#icl-?S!$e|V*4*2*^*amX%x>)JhV3xAM};_vJ&wXa;Rmb59R!4^re zp8VJIT1t;`=SPI+E0NZo4{HtIp2|nM*gGBi=uQNje24ryGsibcqVBNh8`XxSvejo= z(F?j4xXC41!6$C;YdgOIZ6Ak(0R$kCId9VUHF8C!$mE1fBD8NIly`J8z+rD=Mf<}d z4a+y!Kc>+~KCvFFpB>g8dQ&^RF6e5dO>> z>T>q^E~;8OL=pu{e^^3V?K=EOT0)VQiGrcV%$S#rg1O*VAxH)-kAiu_%-~hGh5~R> zk$1<3U5SFx?td*7885d@=itBGPfI!V#~vQ*J4jDW)jZ5fRM*bZoSNyI9Ltjl;JJYL zh=NIAXQ5|=Ff=zXGS)ZNHw6GB)nBV)tYh#S2+Q^dCLZX6ByC4;^JhkrCxHjX3-k*l z{sDL35F(Dzlj}cF&h`Hc6UO=vuqS0=VlQC*gZBQtmXiND`xij)VF|}ziV1g!?cDFt z?V>P*K?DOwglTt=b6qezUqdEE?(bC;0EPGU!y{20!LI>-mshE+*r_}^dOXAE<1CRz z59$$R(X52L78HGK=Ap0x)zgtcmJs}MDn~yhhxrIZM^em`tTc~|OVcYuNEpteq#=%L znGaFM#5rX)Ku-BuO8W|!SY@#w3Z(Aeph|{|fv!=aKvdoO4PmXm#b#EB#RI|wQ7H+{ zhdVD3sMb6m3n)1AE=wFIG}a+G`8jeF4l}twbYk6#MC6C`>swm959Vv4;vDD0(`sv%ECvZLc;voQ%H~v%*OIR-l`@MgD9g zCw<2X$(-Adh?iA8UWQ)!EMM?=<1%;Of`2NB_9w98k<8@4$?G9>07=fwF*j{iBFn|CvBOMI$ z*ng2nH6MB#V4Z$N#7QfN+6q2^N|WvAQc41-oi<=5h~OV73UNsiOi$NSC> zxbTmf*Z_)rNrjH{lS|ZK)A`~{VvynZm0Owyilj9vHu@_;Vg0nXy~X5L9hM?_KSE?8 zbZ7`-Feg?B^737b0@I3Qi6D*04F!riMrimsk)5wH8x^Qijjk?}6%<7yK6Pe`jkUX% z!YE~?$0+&rZk72)j0yvGrRKOSB}$7yB*)NEP)t`RQ-QqsQib|Vnqa@OC*&1bg$R?V zz+c7kKv{~VoJPul$$-i_A~hQHVv<7B`sOuj2UZ%bd?t?XO8>%@r3rUW3Q?%;zOvZ? z7T1O;3+$gjs`z!LKxj&xLokuVOCv=_Dy$h&!P${hRLS78ge1__=>nr zDp75VZwSkmKx}5@#jjNqE2XNTbe_7f+DB=wYNdDR22l~sBHG_SU zfPMU-o2f8vZXHC+&mRXQAL|B9gb4(%=f{G8hiqt#Y}ASF;Ez5F5UmEhBU?plq)gvp z8GH7Cw^fC;gDzSCXqhhn00FWUmQ#E}&lqq5+V4UeOkQyI)^GGTo})(akY#56Xaf?C zl}n7_3YRWg-wVxJAj*MMY|-oK)H|>)8ZVlEiQLc5apAtET?`Yg$oh$}dq_w3;j~u_ zVv4u$tl!7;711IC_c&2kMo#pl3Z5x>7OW}9xZ#EPE-d81Sn)kEB;dlSPHqrZ!3+_v zGnm{2VU+!G4y424XH^-zeMTCOA!j^-oQ_C{>Iv-MPWaxP)VD4)s}N>4^HySn(z+J_ z&ViwjM)kSx2Fbe$0`GOhK$mG$XR7vV!C9E*}p$N*p$e43sZ5KO`F7}39 zLL66*gR#ATsNj|$gvCi5iN+Wu{RpHWDSKrA$_wOKa&Xl(^+;NuCNtcW7e&Tdez$tB?jUopj&ywk-U5p<+)<_JdbVWpTWu- z5|HgusRvY@{Mz_aJM;J+8zgTjh!~|9+lYdk(ZNHgE7WNW2;Mlw8yzJmAYG_GUQmbd zJ!2nA_`e@SXz>XlG2-I+UI|kXK5xa$HGG47Z>w82oA#e0s3%eHsOaHk%MhN>hOrN3 zRqRb}wwNk|TEy`F{+_4&^1dFQ=e918a(9O8LbNI(X3C?2=xB=jwfykA%q2F0F?paI z=%aO}7prMp?EIeu$Z`qH4AKt)V)!HA_}>YTA4SqXwM74=?ocv!aW=Md`!{Gvj+>Rk zR6rQ*ZH%m*$r?5X7vkZzevLotk#d)5El9zEud9(tv{B%JZd{fwf|gG)KT$!C;W8H_Ww^^^IsiP z#o5C8UvS4JVOkbh0cG^NH9I{;Q=j}u2#O}cyj;+RpbRlgP?16aKOf0IS}2{rzNsi1 zDJpz-U?>=Ce}c@uFuX=O>K4!&2ydk9+smws+B)%`;o19Rru}*Jx^@RpTAvyqm*353 zQvy$YxU@w{u9p0Bj3OC$4rGewd`>d8dP3II!)lh66KF)aT+z`K;fzA~>%*IzlLd(q*BSfkE zRh-HnGgQ}Zg%U)^!EHxdsK_AI%4p5`nPlVlr{A0CiK~86y9=lt0#a&>{B$xjWsgf} zAbg8A1c#u2YWDt&7hv+OimiFDm%4Xa=20Mw4vo*R=Zj};7K+nD)A-9pze?wTcLL78 zz6Ls2<<(a^n+7`Oi_v&luv~;{9xx|KG~9!Hp%}E)qREytz(_gEfVso-5QPSYfChSXaY|7F3<8`i4T925l15UJ=coT?*gI8_6;k?Q&uSps8EtA4#)1H$p>9& zXdpHu49-YDKb>E#-XGWg{{0(D9}pB2&Oh<8A=&)2cow!YS)D;MMPresQCDdf>E`-O z?{9d8?xu`2%5zi#$*$#6W>a{SUqR}mOyM$8+RS)gh5-p<6ZQI6kzcFI$y7S3pfM;n zMWd-^BoI^lUYK+fKS|2D$sjn{h)Pr+-ENdHG#NgEe16|#sRXL6JIIKW>9o4tHCps> ziEb4pN@8W|gQb97hP7KZZKa`NW~oyxzEt*`tCtQ$R)nzLuy}r3rz6M`Dy%`!g?B9R zYr~eF`Y`0nsa@rFEmeYvuWn^dYlf*!syjAn0#i%31n9|`F4#8PrfIV^b9Wd-)YBub z@9rSSkh`*jfBD$0_j~}nlQ?-=X~3X)d0Uv9HD&8Ljg`(08~aHo<)1;I?TkO>=*NcL9V7EyA_3})SUT12QFI%g%`EhiT3_R*J}V}& z!Yg;o(jFt~+KYZA@ zXYsR0G&s)oI1%+P7b*H`{awMWqFw1kqWFtllB#I#oIczyAV&;ug`|fBLm_xm{3syZ z<~il80+6(a&}j`axDBvE64^n=5($;=!=brOy)l`#86h`bbGe?dNPRC!p2bfBq{}t{ zw}XJ}@R>odxzPdiFrat?*}U|{;Hy3v0c2r8bBDEbZV2OzGjh^gAuf;Py_pc~J39d|Q)Ryf5$YZluB zi~Ga3|DJp0uRc548OBn?yvx2eCsAFl3Zm9LVn^JYy<9X7KQV8!YV&i^9u&<*QQYRuYKu@=FU3l|%}*Mzxy$uG043d1#s`rR z?b^k)8SIDi1>Ao6CT(_@xK#fjYtsS0J+bG4H^kWrUwkIQx-~oqo8&DAJQ~J_y6gg_P-jhjDq3jZp+@FE`8LT36cUYQFg*i*bJGl>LC5_ zPYg5t5NlRS<^5>Msd+{1%ZJq^&5rJvB{f%x3BI z@FatEQG+-V24_9`#cpR#G`LzD*H4!4py%@RTLqe@zyk5y=1NnOX>{}0 z8hJ%F#(%^p!R7g$3@Ullhes(7ANe@id_w{Ow~`Nd?$GXDi^hh*D+_!7`QL{&K-jGQ zX`seGbH@MPKuP|if&NgGwkAgZpeDr)Y>l1F4Xpl)fm3@`!&*iC3X#Ewuj~iQL=TpS zLSmIoZGvQl#J47fwnrGNcMt?;9vKiESU|w)l-X>mZ)EOlWVcu(tGhnrBnl(oz zb0*sUlPFF607;Z0{a_Jp{?_Iy=$6kfkS#MVPI3TFQrS1%9F`;Lln6vpmPg6G=9K5= zZvAr8|EK=uM&3@XH$d@95=(O+%=}iP8(}3kU_#sG`zycZD_JDCWl>_!*xgoCEpG&g zfv9A7@NL|mcvYHvZw;d+S;ngLc{s5Yj-;SO-)eTZkKbW~vY@Xt)rg>=JmY0oqP#7YYY`i$ zFQ6n*H3A|85g;y|5sZl)LL%)FK2jph5LlCT`>a?G^u#B_las>_ zBfa%qJp4pmuZ$cdsRkz?YjPJ98wRunfsWj&XJFJ5HMZ)81`MRkU#)~?_OwQh>Y`@1 zg`$T2MV98g)Di~@HyU4RG94qG!n#zIN0#DBORC3q7>xCyrRUOeBuLwfLa%SLZ_Kql z<(b1o$p=?fPAlfjD_AIc`_U7H-3qe^8AXP|VxF#=R?$n5Sx}!?&oRk~S$I}A<<Q zh?9ppW$2V0-5qJeSDk&|HR%vqV^49Q42aU|jX(Nsa+FJRjg_q$ae)iY(rzXVQ^$;! zIMb?Ck_iWUVoxZ|EpTpJ4g>{kmNbPnKdCo#d(F&sDpJ_k+OMRgvkZtzu9j@0htkF@ zG1QacZ}i0;P#UHgT1dYa2n8^cIcqdq%wq?aDl!P6B@{(q)G=m88LtFFQ-Ed`AGD>U zSzq(;tOGDT?d8j^9!^46VExz$J`0Wc&ZZk{E~~ zA?3hZS)(t;q0Ks}YKrVMGrBFyaXi3oK|7EDJFrjUE;Rg9qs$p$iqgtVpGQ`h$xM0F zUEylsc1AhiaJ}2e?^Ij!5m@t45a5~Y+_Pms(pCJ)720#b&rp!d46TT$k4WU%$7?Zu zaE?#RpFS8le~E_fJ+9KL%-@IoNKxFlJ+}xoI}$F5cZi zcp<@^W1W52nn+*QilUkl$s~KuD7?`rZ}nVPc;KBSYOUdDL7A1BUZzScfG-{HAqAA@uQ+xKjO^nb=+nN-oy~%y;eu{*!Lw-0Y}@hc3HljC&EyI zB|(v7S*$`(Q9yAy!IDsgsyy!6ROFK+Nl~5-begciJA6cHs}Ga zVq@^TG@>{LGkgNBxY72La9F=3b$(xv>4rx+E2!x0zL&j-4HID@UWbHQBgR1FfQPDt z=t|=qN(^n1Ox5u?5z{zz7>dXhcJ_$G74?l_0yu7=xmlzYr<+}mmm8o}-9z_oKLp+V zdiQiLT?1I!2|sSe3kE8DHgJgy9dgU0Pz`Qt*m6Vi?*Rog9*TXT1sLV^>3Le$+~>EN zygL0q=UO9MR^(H;&!+Y%^s~CZqON}>`65bSebZ?tox@~l8>K)eK%2JnI{IkP3ezSX zaUXJP*n+p?kdoO!Ga-tplkLi=Uef%Tx4XyIGd$5f&gu!kaR+zX)oGdZYD2y@qT}7g zVV?Eq_Ve`~J9tA(>N(y8={>!B);@+fu3np!9(S1L@fTZEuAf{ zNwQUg^te;zC_s_?TX~NyI=LH;$_tv!{_2Ji7yh*(XKc4zsHej073pF!-y5 zu6|wZu|nHsa<>`ASFE{Jra4ajUPXtsT{O{a^zcpkiYE~|V+)-0grOZY@m-v=Gvqh{ z+AeQF&1D&dEmLx}=p2SIavj^vi5xJuo`u)U*KVKHyZ<^|s|)FnuA8^xyTUaKT;Ph0KPKM7OJbg^*HpM9&<|7i{XpKO4NlZm6SiK&IHiSfTd ze1eYL5cppvdO z>Om8`20V%u*ui*B#3+A2D8+Y>rYx(4>i#OIandU|GXx1D$}w0El2q}HslQ3#__im| zipmqViGfeYl0}r4Ul{@=1~vTdjpN77 zUph|Rxz@>w(}Rgk#JmtA5}XU(0<0zPdyTsTlQYmR-3|j?|c9ptwFO zZzS(Qu|S{*aOe_COPDZw|NG6+TG4zF;)L*MsMiuu^?u4SBIJLTOfO1qtS-stj z#NFTG57U-(jFm%je`le?xldP@+=l)FX~fz>QF!Mj2Swx>l_?^8R~!>tlPQ$X=OE?j z)VaS!RF;9hLamhg3im$Vz|chJgxx>bAUep+rsf}7_3i(pRT=(&!R$Zw?f+s|iT}NQ z|JNsF5BvWDw#l1{SYikv-}U^JgZR}$1pT2y;o;E$M1g>bVfw5KK#U7ejS1MpvPmLU z^+BhUnMU%?DnpN5Gxi5oB18u8j&>sqBtHckf;;0k|P^F)lk1t5t8V+O=-37+?t; zgL8?m&NJk-mZB5d%PYt86niB6MYK4p%0z-lhX=k2^_a+}71PFVbnfS|)SO8){wF?_s+1 z|6&~_^<=R=pa{vcL9NFZq~xPwklN+mboB&FR%_O_pq*tE))V58udg-uoWlC;VUJ3= zr}ua6cECiN<{WQZvsFG`3UjJHBwkZtci+6_L7?x+gS>!f@83Y)K%*brKtn*ZO(7y6 zpx6f!k^4cnP4t64K&Bm>A|oK(aEgiZtM>tksrymxa)wgk6YkQ)g!z>LWD`;5>Ge^H z_4)w6zLKB?GQ_Nx?7Yp?XF3DJh_tmwdWVEJp=TM1kP2c;qxIa8GVFxNq6 znD*p?sh^9q7;4fBKqWHkj=Ogul$Cm885;zRq@36ckd^un@;5ap?x6%Tu8G`20#w}qB?|lJ1$9K zFrlI1jii3G-=lHqU^hVHuZ#UWwFl17RKmXg0QD>O&~$>N&>}H2tCV2iJ+Uu1WP)Fy zNJ1WPbP$(#`~!zN0VGG80FrAQ3m)M!hRFkp?SfN!1hBUd$w$h*b6G&0h@Qg&Mm<2U4Y+6pTWJisI11qx5dwY4bJFAqDeHRFtGUE zA&wVCx(@-|kWyO$x=sQAHUULkJ#hRLWAGUhsA)RJ;3B69<2KGKvx%s`V$w@`}1!)t}8h=`U%bTuZP#s7aH+h1o2lh5eViK7VW>^V8{Lyh(w~hK&M($>FMlsKS*a!LsCGBMz4v9rILO0nxj*5 zGPO#xM_V$6{M7!ESSs;IQUR9=LWi@4zjh%3rO;y4V}t`kdCr+#Z(=ouT;Ax`0d&Kj z!>mL5u6OBaWR zhfFI^zY`E=+E}7_eq^^i0f~|ewka=}a#@8^lbQsG9s;*B^~X@fCQpVx%5ocgbX?pA zEchpX)?xNT+{ja_?Ds^AV@%~s@j*3uA1{s(tv`&B#cvf@Qs9_`+gnvIX7gQoPjzEs zzNE<`5#|(XM1k)x|3dZ=OnY)D(ek!3^k&0*Mm9EjyRu5v4K9M-y;q=0-T|wznHWu{24CkYWa^q3Ezq}1m@o!k1(YKV;GaNC(CLCW zDAnW%EW=w)8;>zbrAcI_0!6iTgQ%m8Cj1s&J)1UU4P&%)n~?N+sRZxRB?`o`GC7T6 zZI_LV=Ik4$=ZuO#7;hUA%QFq&bHrlXW?46(sai_QmdImlB#dJ}4Yx?nkJ|Uxs)nQe zES37vi2;KSgAkaJM8d~Ju$sJ5SOe*Z78_*^qDmxoEBr|8bkm9ZNdD;JHPx-< zG)*A|^GC-`ZCfN43Nk8s1O7uc*qQ?e73EUl6p4yW>!=4Y<`DB;XY*@wNGcp=qKA~_1WLz9VkmnE61MOgVY&4-|hhOvN=IGZX+|2vS8(zZ5s7WOs$ zS%|>*vV-bT@vjT9%{=sV95&{4+-WB^{dK+a&I$gj-vi&Fi0=?|`$!xw>8spJ;5)@5 z-=KuHnSAb~y&L;f7p4@!;G0SqlS7Od0fsS%jOSWgq$`dj@xbhX`$(sSSzQqGw{m;^ zTS+_LH(#6{2q9gSXoc?~oBvp38wx!b-Ohu5FZ9Lc$xYX4D?up{@-dC})AJ?#&_|o- zPDDH{w%#qKaqK4khN$}2uXd$Tp?mimv#DXYTV?mKx*+R&Gii#tojWtb_87^bLZrQ7 zS)p*adF?+eXl{d+5_M36tqccj#o|f?uPBF|VF^)M0_n5MM%({d1L!BPJf;26pgjMU zTm1hw)A%_o{HNT)@!$C=bpJbRO8%c;{jV4WX*(w;X$vQ3ksqPwzwZsBm34j`HPC(G zB*Y=KFa;@+M@Xwx?f|RsP%8ZuC&WO3&4m;+wK|EV8W0-JOamVWD*rryFG16FIf&NU zi<&_>UqpGHMD>m<_OKGVrC#lw!S7U8?$hs6O?JF-_#BeGt(AW@_Kszn} z`)uXOQA)S!%IYk|PrV>0QMqy7k+U=BxY<%K#8FQ($6=5J`yS!P){~}wz-V;*h|kSl zo`*#MD92rYEcAJP3Y1L=LAX0=QNVZCD^Ga_TFq>OYRTofp5qm_NY!GH^2ts_Z%>@s zOjD@crphGgu??jk_f(VVdcm=;zV43=Z3uuEzN_N@}$^7Pbls)S}T_^!?(1I`KqASQt%pLxdoVH0WCdA}c;%*`lCm=cq^@ zpg`J{x5>mZX}DV{Ynt99QvO*IKnnsQYZ}!sIbxYzXg@M#QOq*Uc-ZT8+8imWvTJz! zT}dcIu92xsYk{i9Rd?1vH7CWto;)^N)v*fbQe0$#h-dY?D zeQuAioI{F-t3tYs#}}8pDKb$OE^ql{3l_mODt!G2s%ABHv=PBbvx5TO19st@rgpWX<$zf!ql zI1P)(jK^QMJmnlm9c}ksQl2?GHF(MEo_;frc?8XSWm{dNU2l8ek<($g`CSu($N`z zYAbC&`YR!}%*r}@q$q@vBLytiFhMxf433_Rh-hyQ{;!wH6bKnC0&_grf|)uXQ}G`k+0po@I02BM8o4 zQ)Rx04*h3)g9qVKVX9{I6}~uRV?6RS4aYE$@I>&J$Q+-}A3d9=5h|lQxIuxfSgDIJ zqCPD*fx_3ri1NF$V4eP=S`)|Xk1-3=Ct7)A10tSa6766$@lZH(ON}fAqcd5ve6_AK z%s;hpzPiC@1hLka4xb!S22b<7pBly<(-j&TX8u2Xonw?FOwzVz+O}=mwrykDwmH+b zZQJIwU2WUl)3*8bv-|9M_j|Gbs!rvvI+>9XciwS@fvj|p6wJDlr}bIxNNjPn7R3Qh zvSqZ;@hx*+2@MU5b8bx}RF&2ACC11xcWla>dZ;y1y~9auY`$AkKA}sxF?%NWvYdy1 zq;eX;sr3-~$Y)_66x-1T3C0y1krv|>@Ql*!* z1&=<-(+j#EEBSI%`-3m=Ut$VC*Uq!|OHASYn=SRflg!Be`-b?ZaPs$_P`9xCvLgPo z^a)blu)=Xc;qBg-I2%7x?=szR)|S<-k__J{b(u5XE4G+Tjannal5Bd}Hg=UETNw`= zm3i5T2nrI=_f{c6ffCAjAwa8ADwp@?DEYf_U+^SSP>M-w0o8Min7U`^hM?Kq_Kz`XIo_UZY z>i0HI*|b{~-0B*hoDh6*B5+?i%8@$orvlP*PYQb$EuaC1`&$gjHAyy-1m-LFWo7m8 znx}LE6=X6JNBEut4zk4M*RL$uJCub|eTikNnoH+NeQ!7E7VbqH*&Ec*JLN_-r5t{} zB*D|9x$}@T$1YomlMlpik_jbP_#naI2Av4Qx35?_)4vx;^ad=-MQKlaeT%_MM*AMv zL5LFO<)$ZWQdy;2;Nxriop`c>aD(^OjH@-8&DtZKWaC=?EQd2Op4r)^({&&o=eGLM zUKSx8@;4pTeS-Qhe+^&V13Jmy>j>sF0_~W>tvyukrQva&(W-Nqa!X@V;eA4iR)2(6 zr%Gvsx`B2HpWYSSXO^px;YTWEPy9r>F*DGC6@{4wVh)MRO|mf|3{#P|DU36KzrfY4 z(nCxzM>mQIxyXA(cBXK%Fg9wszAHtc9eV~3V+@keuT)cEbwO9^DxKx8EYr{9_qTJ{ zg@%bF!Lq#VE-14m%3u;_@(Cw1V}|CW%xJTSl!DbXcl>a@z0FMAa-iagGJBx3i!#AO zo0~B_feU_R(kf?&A0e}ayW1_iouS3CTsy_TB$|*5b1e~*GN+{V>3B{ca~sRa??9ij zxS8~na}+ajBPbF#YFqX};p+q#6y)hFJp96_AteH8$>8YGL zz(U0l_iOB|Km9uaoj2poEO(5f|L>H1s5Q}D;5M&DFxptw77 z_a4*7kCGp}QTDVkYp2HpcJ7oqQ?Ql!p@?*sh-uk*s7A7#Huu}=H@G{i^-rKim9e8w z;)xu7LYrF-;V^%wnM=kck$9?N=47r=fH(HJd!Oi-r-EiEv)}2Ai$+h2hX_UNmGg<< zd^Mhs#SLXU!<`XAKLR4QVPVA5IbaU-d&$xOglHQ9p_%YG%=7f_Qy;K@MG1oVy`$N$ z2+{i={R71RJxcu7wekOjh=h&5+%vsSagU&@=brxD`?LK_^Rx83rh@=GP z;1E*Gk+G?-Cg`L*k}%Q~S~e76HGC{i`hKE*9+0mS7x-YffR==sm-L8BgLTnfjtCZx zUT?foSG-xvPm46pdQ4X#OV6b#ftoJZYM2L{6^Qmqa#*w*yo?lri^6Hd7F{8cdPLTk ztwN(C3{P0DQwFMjxS3F9G!xOwWp>p6E6msSNPnS^AUG8eSEDO5tQZ__zc?!oz@Bw& zAgf09oU(Y#+dDbO2zKc2lZ`~8xkx(b7ewkCRq0JoMjPVcoOG1r`rzQHg@jH>-9@a5 zSdE|RL7d8f^N*OO`5-F*0xaBs<$ZQuzw+?BC&vT)lFD6d z0ODg2=RChVls6+WstOlzb{1J*$I+(v+}k3k4;nCb=MaM3f>w45M&uK^Zy>H=MTR`P z2wvi<5DecUpDXsxIQ=-Zbwl)Or+3Z5a#3wE1E!GZz}q(afBYn1etLg*7xWea*gb`cm3evlvwa%m9#Mm<7N0cLFsMJNG~bLo%gS!XKIDbhM)X>Vg(1k^e{W^2N*Aqhee>9c; zk3Ie0tGmA+lT>BZk9$<7TcGonP_ygKJ89M4&wHL67xR~ulss&*3kRkaI5T_jU-*1c%6v96xMjzW`QZJ7^c}gbl*9sU9=`_RC>`V9^f9`O_ z`%*4JC;zdA$;tbchd9Udn;FQ@-B69deRC2(0km8~>|Yv8=J)YCBq|?~_N*-@cNaNq z1p-8GPBA7{KzX%sKS_y^Ix8}cRzd7_&UKPv94mU%>yzQADz#eR5y1T8r1(H8#L|x@0K~7^y}jM4KMa)ZV&<9*8$8lmFISH#x+m|q2=X%fp5k6f zBx_PiFrVMz9|tDtXrGcy`;j!qGPBuE)Wlz*p{;_aE(<4i`3FtN6mL|m7P7pG07 zkd>~VC=yCd5tfq+)OeZAiEXv!RPwlxPe_!_yT{3LQC_6OryAc~u?NRT9L?-HIx308 zkk_Kx@`>>}>z)^RL?3KQ2rv1vV6Gm*;O;mJQfvpD6-g*T{p05++TDk^d8XaPiqP$p zxliud+R<8RZ1Bhphn79idE*>F&mGsUl!6iG3h^=yeGUKQ6SC@7`RCQtTE@{+@)ZDZ z(dJk3h=}F>@(NtPU~c;m>jUq(U?(tWO}^Ok>g*MsUpOsz+H!Q=T+zWb^k{Tjo^oOC zJKGNF_j5Wg&q1btr+YMZ2z8gQ2@=S}l2&FP5$SeAn}ARJPxc=y)n&7p$Qj%^Evh=L z*a2=3@t>>iOCh|nY}TkNa`z!nIuc11*5E3IK&ZXB`Lyn6FA4#c@PU|?$mHd5bmtVl ztx9i?r5q-o$X!2$S3c*FNqj5)TbqIN^MC}6>ezzd%PEa5l`sZ57o?kcr#SK>&I%go z`TCaM(1w%+!C>Bk2gvC7dJj~5DnAH|4exKuM)neRdL+;JlK2bbwkV65@mHQSe+C z0^{{#>le5*>rl86-Gjf2u!QDL|FCR@A$*D;TqON{uu8gBYMZ9ou%AO+LI3fOdV(A( zCkXT_OOW}})&B1S^M6Fuf7TNU1{RM0o+aqY?8~6_P35ksdDKq;Qb(*d&{`X0KRTGXejNTaKqD;rND5CU*=Gk# zN@T5b_($Scl_CR96Js<`!0*wPLDIgrT6DdVtH-+?WVY~;1gD&zg^vkr#dmz%5FtvV z47K(+%$Pi*u^mG#9!1(7%@w~$`RO~K23^^UMrJT zNcMQQ-8j~s%ofmuH55lrCjqPH-udkGG6qvn;Yhqq6+Ke2`~IlI_B-H?($ik z{KPbE)Lv0ldzq+){GXE*oeichbUcjHFZccvk%CUWNMd3OQSDizN)1z((MXt zGbp0MJRm`}w;zt{DHEZKV2!pj$Zka0iB)2;<5fp?mw8vwi8V?-Y$7FW6!XQ;(wG_Y z7)p;YL$Z$AJ*ko9;3QX0E19YJ8p{IhKvyh)$l6=LjB7E^8!X-VMB$xaK&E;Ej{pF} zb{+dsI|GBkeAkb`kdY5{c&z8;qhB29iFdQ7QM%s$e8s1wPdD!Uxcp6r^y(2G^Vi!) z5zZ=W7?Rkmtl_FND(&y?f8a( z)PxCFyEbSrnw^%)rGF~^C^crsnX~gs7Vso6A9~VUx6cxDNVb^4T&sK6^t0zuMhw+) zJypXofH}nw(&-NsuvDnyK*GTD?@5i84TXwiFx9o$s?gF~sbm{99JjYJZ7}p~<^i7! z{W)w4dB)(&4K6w6s+BC>w0G<~nHGNb77~rSOo>p@7Hx+_TU&&_nx)I=#2vknI$tYJ zP*)cl{d;-1jJ2&Mb)vb5td=AKf7$^dM5EK-8M>LgBwNbNw~DUL0vFRb&1&(qGxKiu z8&bG~-Y}w!;!l9@`gs$@hPVk|P~gT1lwG%e)vwxTS}2$lZ@vH%C)EkXehaui)0WGIcyU>)G<_+;7NRaEBr+e(-kCVV`pf zqY&gy_krYn#R}7=XMDjKWevjnldj-Wj3D@(m?IoT-jf|%yH@o+wWm3ElYEz`k-cFm zwzKI?FMS=_`V$DSHpw42FTY~k1am1;~?zk zNoA4StQITderdrp-pTFudJ~mISn4iKOJF$!m-torxHXoWaSqWp%xY+gU93HJhKfcR zDj#-WT1PjS;WDzpdl0L@G+?m;eTF>#mAj z8k0k=&p%vtnDZkF4>EP?mRSyNeNK^+bKFbJJ7K?)j2XbLqw-?G1hE{`$b#j`&FMJ- znHnvZ&!3BS4CQaqye>wk?884z?0u{GKTmqR`GyI$AookyM!MGvd{88Z5-QWq=JX63 zW$emI#LM-)>h)hc4O_2p|0;gS`8oWAzYgy6e>}MVLdv_?S{T_mn*4{8i}&{t|JO<} z7gH1Wze}aRJrU}V?kWqYANn_@dZz9MkO-0*SP@C1AP~jYast8#Qb)Dm*6~y_Wb`{b z#-{GKVE$IxRz(@kf)%dfh|_ceCP-1FP5RQ>Yg*ct=UtbtmQ||P{ExC^$e~+iWOf%m zkJ(-qoS)BAZEo4_$1`)^&~{0INwJDeI@VvTXQNASDtuj<*G|@~2Wh=xOazt~9MrAl zEBO$mALi|j)=dU=fqh|7i3>6sMvW_(4J;@C8k2Yci3@{&)asX65 z3M$!$Yf(IGNG%IRzA%wbBBR~ybuw$}V=xCwA+SU9)O;OD zEn6SxZZ&5YPBk*4d^7`C)0l(usHH+C5PPjsHm+o6BZLM`B%d}v0u&1GOyaV@IiNP6kgJxYgxTOgmEVfm0%ozv-+vyb!I!K zn$jCKHg+}816RGWG}0xBsPm0NS;Ld@khy~(d`+k$hUpxgm!T*@2bzCKA+RAK-E7vq z+o69dFWV4g$tPD@k)O2O00Myz)9~br9xXIt^?6q3hWdV77e`qoX<=(3dleEr?S`oY z57xwlF_n+Exz;q5)7uv5au1GN4&ED{!p1v`HaA~5D|wMVk17DO!wQ!kLRA#amXV|g zF;SgDyUYSGs)8;p0FL`E&~1MfH053WUOmoTq1Rg z1A@+(;yv6lTE&CNGQ#dPOr99tH4q2Bd(RIHUpeGkoKFrRrQIrxbJt>7t%(kklWHIr zy5)o|g|qP<-r0}tGg=dT+lcn-|Blly42FkuzTFjR#c0PDB#$f&a0m~mjXMo7py@Yb zWueR17>V&XunPa7zTr*+7JZ-Y{^k7+V9)WD-O>(hP8J5#S9)R?o>>16! zqg@>s=vOL_Y=j||02qy=9SwhbZ+Nk;7csLSLB^+*`-BDchUF7Qg~dm5^NJG39ZG&}6L#pP;VN99QR#TmL9%$2`_ zDAGOb&nnjCJ}1Z%bs4dXAGv?$;X%rlGZ-UsH0(%*7RUqp{G5~il*VN};Lt`P0XaE) zZ0quj$-inEUzLE9j)uEt?n3guIBgg&VwLE#^2M&?~GO=ajM7j+VCrmB>^uUz@c=Dr+x57 zV=BBM6FRlDyUcjh5lfQM zJifN2Ml;Mtv^a#V%uUaO`=%pJ%k7>#WDm@BjW*ywz4m@ICk=ieBMuv>3?|ismn>E;t!SC=OlY+9AH!eoMD&S{lkygPk%4fI? zmYqG+ zkqPHL?jc8F7r08eAMLCOd}dwPI;7fg(oH!zA)y_#X-2hq*iP4`jj5sc%wiV-Plr&q`u+q_1u9vbptmPc86i<+Ia?ll zjuUVB{diu4sESM=W4SqANqc2WP+_2^R_cC|C(K1je`K^Ef^;AKiS)O%;mapfx2ZgV z9@u9@soFaB4Q~wOpVrxu(BZfS1&y2n>*JBs+FQ`bJ@(<}hQiRqm{R-YJJG8wId!wl z-oV<%fqiyy1fDSd>DxVGnF-G8nwseB9>LjDwjF+vxDJqN3J36Z|z z_y$M8RLt6kqIAVDhe&RK+e1bx>{3X2!`xmI(0##*;3@mjsY;SjVD$a}+>&~RIpzhX zAMSldic{WCsF4b(+fE3Ka+co<*$ceGqe=m>cILXj?gIYG3)ds@!}GsLyiADyNxu0P zpzZ(5_Wr8Y{;tu~J-q))^)`)7^_Y0-;|u!@_xwrvk%|l%>J)$q!N^HSp#vc}(mF}# z#}CJ`AsV%s=!zc9Y?|_aR5fX}tCyw~4hgBRt@<=oX?5f-&^g>sTiFzoITfj(tKV8bd7(HOqKG_(Ywb$a?q;C2Et4Ah;el zIk$0qhx!f^?!9wL{X{d-{l*(cD^5k(4+39V9z)kcqa6cSfR)+kpW$5VP9XIY4dLji z1jgxKO)%hw$~xSL!re_L<|LzkuvasiiGWS(5!9`&8r|Gj7oY4=7a{XbF$bPgkK=H$ zVOWfafoT&Zrlqma5?(bkN*dY2226oz-Km8)qPZiS70#^@FBYaPe?(+nuH`gZH&Ab8 ztNFrVnfI%4vf!{GH&)O{d!``6CSLTg;o4>7^K|^kMb<5h=v2@ovbkkpMj<7hqjE$~ zcV_qw6EqpVByIXU9p%F1IaSBOx`73Ndaecb5!!G8qD}3Po>`3A0DIW>)antztq(~u zYkr!BR|{rvl87Y{0^(5J%F`m(lYvnhi401Mbyhh~ZtpV14`$5oPoIp?0fspf4b(;r zAevpGK`@j!3Y{ty%mPN;57xuFp5kKn>HNgfujbief>g!I8(AwqI$q z;ap@lAvZ&4Gbx#m#CX8Q01blPweYNF>Sznl<8M*#d~^lA?1{SL)m<2MZ`ox;i^dV> zc3OXxThHG!g&ky8hglDIoB1TN3$dm)(Kc922~wuYq}jhX!&3eF3tiR)$!>F*u558; zbIFaVkhtloGoj=jJ#&4b^s-J`cQ$*95gw92Q6Y_ET2 zYfWnLZ?zp2TjDYk{e(6C9wU>&ZYLE6h+=NQ+RtPrCc_*JNM7e1WKKw&;iPbj!FI z+Q6kr0`m{VNXQT+%ET#oMXwd9Hol7pjmK_I!O+BAIfujxJIjdTv2e!V|KW3kEq3l? zXc#K1;_^*O*sVI}G^pBH0`m>nQc80wa2eEA38Vo4J4P=l1y14O(lawV7Lc=Fd2>W< zMcC9xNoHVraToFM$M9o35r2qe&jSa!2xYUDujUMedVdfly%Qbtj+6drD}j~TA1WFH z{llfL7ngPI%w)|KjB1vnQ6U0?9v=Xt+A?^(??^gW2I-w7lh`w}J*9F{t{*;wnt3kls3Erz%(!xhOGnZ3i>4a|v} zy#k|O((Kf>>?u$}Yk5nj1&*Cwe6KdsGE1~otE)}H+T~>K?-}N>3%xOwXd|xzHzaP) z_f3a0>-qOh7*|#lHB>o*#*Irw8!%zyP`0PHc9~Z4*u*>spjVNVUKrc4?PgGSdDXn8 zZQlf zO5NGLA#X(`DuA?Y61-zwzG!iITypu2YoyQ7Da<$6m<0NrpCWbMw3zEs$*ZH<;K_#A zcJa2A;_$y~vn~s96EF4>_PD@S=?XcyLQfsAg*XOM#tZ_lHDP{4a_jXFB$z_fTv6U& ztufbLxn7<= zRiAR|ew#e<;DLP(DQgfH3oiOmYoKgMv;po0m+YUT2vM^JnOJA+hAb_DGtGleM7bSAIt7G=;=FR1CP>#-K;*w;`ndh< ztOQ;01Mse@;l3J7T0qw;$gehBK(;yzC3_mu;Xdk+v-p#Qaa;7H?tA!r#nV#3B`yV3 zcEzeU0?b_n zmeQwjP&%6IC;F7t_teNWsY*zpSz-3wJ=%wo0XDvw$NhCtGV?sCe|z#K1vM|e}?J4LyGm(p#9$qJ|^0CwiJr``TX1*-s%GfK;Q4Q@O&v$=A-@||UgVGkU!zJB>hw3&}@d-0LC&!`G z->ri4{`&b>nuUaX6@vGbW|<)TGtK(nb@Q(U|1hDue6isEgZB2XPS<}dlQl80RWWz8 zb1^fwclmpcqf1<`+?v2wSL2|ZPGs-*cmV>1qp(7xwtcanSb-!WOgceM`?WyT`oZOq zI?g-L7YO#DiZ#*a`3}js*qDM(gSpesAVUR47i%gn!eWg5; z1%HQ6q2-qeUjhAgoGm7`%K3rRQ|Y&2EmC!Za->DciOGdN4*@gRi}lLPvvG&&Slb1T z7N-N9KUgPXSH~)0Sf%>B-+dAAY?1f12fQOtyfajr$Nj*4pwF$TDX`s?})!0hdz5$u07cOl4GLb zn7uY1&zvT`vj1ed_2YlO)q`(Sp{crqaD`ix)Eq6Rbp;x6x%Sp62VqP|`JS6jj@FbZ zfSll^!cTNXrfHvKXnOxB!ukFw%&go91r+7BN4^CIslw&DNX235swyDkXoqf?oYw3l zy-v^Iy*#-xSt?Lb$KW9roL%_K(TLQ>;woQF9Q6dGQ%t@d2?&#W}G6qvY%z_rWG7)Cp*p-Fic z0Tn{BIXV(dttJJ;-OJo%sws#juFK<>5&BDWy_ zX9%!zC%+hu>9_!^KBdibI3==lMlhmY;$rU)X!X|BbJ=eD_`Rqw=Cn9Y(qQwLm@zrB zl|B{@jbf$Dl|ZX-P?PGa#3}(Kn})(&$!rc-2NbCB9dMOXixCb_%9Es_10zT0uu=+w zsjdj+&mvvNrn#9|2&b(wFGeer&7UBgsN#n;+YxZ_jj~~#F3-k&!mTs&<}`s3`gL*f zN4{U7pn>|=@MJA8cXZmAdBZjiNHONr58142H#gX=l41_8m=gJBcbdn#WmbTB)aU{- zN%D6Wds1We57W=?XDw zp8a=B-~BnjTPxT`x&W%7;$G`XG-7!zQ0I4@ho%>?q@gv(DWJBkq&T>ED%ttUKYGwV zFr#9&^&i82U9!7_zmpE%=Weap6Yk(Dv>-se0GB(`mx9cfv>x?dhMwiJ*HwrA(wc1W zxUz;0j^HDo8LmqKXnbxS_U7#5<}mTNHpTA`OQM+XSBGJNQ3x`>)6Tb}f>}JqJ+a2) z5pAqBK1$FB$t{a`3%}y>3vU&yp`OZxoy2KiiyPYDgf;czr&wLA=o@}pqRjFm?G*j~ z?v3T1!H4?j(A9}$9H}?ykfch1aoCQ1@*VoB3_(b7X7KSRajBt5<3+(Cr+2 zArl?<@GR3bngBUvEhv+5w1n@D!y$YQ((bQ zf;Fv&9nMeO>63?Jq)cSW>gTUJ4;;eNz4oB=%c7_FA3GNQg&zOM9jGdz@?X*KU$0Nl z?ka<*ALJ{>2@^pBtbrxQ--C>SMMOlAMEAg82q7he2+W%R7op+L&P@=f1=Sqz-0v%0yY8_Y?hiIE%xiRT&`xjVJ;p+!F~((AV< z#-sx6?E(9o-tFJqXL+t$!)5HC?u?La$Ux3FX|AHFkRZmukR+&-!Doc=5i4yO!%FWJ zZ&r|FgOZgvsGT5gELVy<)fN{PO#r_$5+kwQ<6I9kwr)riMY`9Z&~1*dP*BSQxYCm) z@j;`V9cCLKLF(aBN9}nQ%u-FW(J@Pl75Gp%HA^8aY$@h3rD52}!S*cdicLi;qTE>+ zTc6%StHtllwepzak51(WOqlLfNG$F$#E9s&?EuAHb23a~ht@Joj0iEVie-SKIZ%;` zo>m+^Hx7%yJ;br-qn3PgDYB@Eon5+Q>X5yS zo#kJft)XIC;n;KwLP;X=(c}0VbREpN=YtN+ZG%9RT6QGLIyiM|x#OYO#fZ@>kW_q{ zzI2BBti-pPYqZ;tr1|aeL8UYHES8{9R+b&VOOZ?8yV)Dy1;^tKox;=`8k;*%fQBt8 zgz5^T=eC>5_E-~_=fkk1Y)(jE`7$i06-<@Mt){Il-MwAq|7_QiuX)SO!DTrX>>GEchVID zcvC|IjTV!4Tl()(v0-d~LE4bzoI;2sY3N}d# z>LR_-MU9WvjG35zh3ia6aqdssaT&VFqNYT)$I?{cN}?J2~8nNyQGH{i&T;l+#D>~IpsMj zY88_jA`rDTdzMvORU^as(lIL=H_YljRy`eB2DX+;%T~0d8Fa(_B(c|IyGj#MRG&;8 z(D7G)zNV5Ipr5kmBY<2}5T``yo)B#N1a$VPQ-aNuP^{A` zDUuzK;-!80imQSFndOD-xOEae%CMP2+qST}8l>bM z;&QI^Q=FG6pWmN_!4mkKpgMK2JZsBA`YX56xbmkv^!v5S9>2N4$vY4n3#`t9vu08k z!7Goo$C3Mp^sgwrU@&JZ^Hh3Z0g<|AVoR*n9W&Tukh5fx+W5+ZWzti7NcD3n-6&^+ z&x3c(6?Ck5vJxk-Mydr?^Gp6Xhg%6hV6^S2C!i^B)hjN(d zjp^l%CXtrCBfZWji~zwEYBak0@6lafYAjRWHAXi} z?L4l3Q#pbs??0>IkT(-|68`1Se+Vs9Q6z$Q`Zdxpc&V)$_GTrqc2V^Jr>zLCyAH-~ zS6;7kFn~*`d}rzjS{Zw3iv3nTR2i!CiCR`XTNi(GXp8j?cx@Sdj5>}lc{>LP)bU_* z$O~&Tr5mv%@qLnc7r1sEMSBDz?kr;L>-W0UVMdq{=04Qik zvl=tPT$#taaPv%XT){Y@o_&_`0Nr9=$e9*;2}Hnaw#%1T>}#qbE|+SNcNZ;FPu%Ye z;c6+A`7Mvkr_*P;b_{Q_v|>A8C>GADXO3l>J4-!O{K^cdwGw7xG=Jr`Wf;8&JY`q} z#Mo1X#g*zC4mejR-;b`%dg3rt63>OsYqawaUxzy!o4CrT10du16e))Q2-FxfeDOI6 zER2}LS4>Shv6%%VX4Qq|tcbC{?G;IqB}VC1Wh7|u9(7t;El-heAm`W|rP_p0WM2os zHmNP$Puss^SeY3TV9uPw|CIa5`9&gfIav4ZSL>x;vsUt5G1fK;V@~EOn8E~PDmo1@ zPI4?_05BAnd@O|ha?wU^qW`jE+}R}Q^zhXm)w4RT6fTT z1{dMyo|)tHf2RH7fWnjd#U0SWNZpFwo87mO${Xm3&O0SKRcaR8EW9u$cvf-wHK?WpKDacAG2&X8h<99(i6@P0b|IBirXBxp~DnUc3 z*jT82XplAy$k`GQ3nf1tu~nKYjnVGNIXwg{uH0UunKKR+ZM|tEDKQp9WwbMBpFH<8`pzp<7Db z92`~<+P8b%*(3T+y59yd=M7Jjla60`lx>U_l*K2N2b^txlh=5zZ%Y{|l0~8KAq8C* zx&6W1s$}WPTvGK#k(n)eR$Q0LI4=-k936}5NlA=`IplWin2n=uZEtp9ZaP50iqbxL z*d7ClTvl;&AiQvGD==A~xkBCSn$0>*djKjCeSQf&S$E{`aquNk%j!7S>}5Rz z<}t=yj?i9av9_zY{pp3#f?O34@Co-(Rek$YzCPGtiNQD4^t@5?u}wpm&8j7$Y1s7K zr4FxN^Hrx(T)h5atrEXYLw>aq7!xh)jQ+PTcJb2lPs7)B{>YN|sby!SS&QF-;+LA* zY!oI_D|cv;{Fg^{`EGXo16-dqHhFKZQ%i}--R6LdoBh1Tx0Ys}{p6)*{pL398rSQO zAGdTa9c%UAH4x5cJ(ZkZS72Kw?j65v9~eH!miBQ!;(XZ~_~xGlwu}3xmSFdC*S`fV zf-R5e!kq2Y^Y`ev(I4&#vg{Bxo5J5xtq$kELEx9h+~Dv8zt-l=4zFzT_CB5@{Gu(@sKy)T6CrC?YR?b8w`9mOGpY8cYyfZIkn_| ze@ew}{T4Es19eH*xj#tTP+n01-*9>7PWUux)|>I8X2MOr7~!(y@`j?)KuXJN6>o3a zmDm&v+C*J?QIF7*r(UY%3@zxP3~G};JVZoOOKW6mn@+L#55>aymfvps`>QL`hV)hk z#}~A)YG!i7c@m~m=(wV?xaQjCn#N)T9_py*2SnIm3*Y^=2%Mjd>@j-0LQUm$;u=xzN<9RJX;jhl0xQbR;9?l}`$LGu z-BkV#CIYhGaQ6&qt2UKLbg{mhCuApaYNfj-&;6k`m8;G@2glXXAFBDBHnR}4YEdKH z6(utGr2jCM=XrHz}#C%wA=oyjODOM4$-VkogzZZ;GH`{Z7 zg)z&6Vi1Z^7-u3jfC7CuG;N;S8nrvWU+2NFZPGAVU4@DB!BU=UeBaaYiDVduOvE7A zs!l4kRZDYK_wU;%UD3Ic!e*?0$SSIJB_=gZ zEqZBGsv!EXxGvHFru9FPZ$_U7z0?*L5a?!w0@!-xhZ2L6xlKyUZ>*Op>)onQ+0&}g z&}q$-vLekxX|yK|+YGOVWH+z8?HQ}`+IG|7>_Wnmc*@3YpT=9Gb;oX9TaD2yHXJAE zRxUhXxskN1z|hRu^(HkP%$LgwpgTC&7&_CC=4={VM{gwbn9-q=-RaCG`uvZV>mS(r zFLXQd^SoTGf=4P!5Z`))a0t&(!F(dA7;6!T3w*fJXNVerxrjoC>>LDMxzKqLn=cLCtajT|HT=m4US4~_6#mSqkLetwa^+|UI0?qjI3V_#)QU{VCiuKB- z#{0vqP+bap;-Qi%Xi9PQWL!BtlEzx+hnXUX5y$K4*Z{6&mgtVj$l_S)#Hl|~wKR|1 z(Jv(lp-Y~*vEUXWE}Mouu})73qcL?743DDyT}tjphrqdP1+aQ`wCbf~MimOeH|q}? zaN>|YC5CCeW%5;)=f;{Goys{okZX1vv_mM}@@-evqKKiJxgeccN0Oqsk4#6T>s1Nt zZ|lh=w1-$59{-G!c1siOZ?~DY$wPGb!(l%b!bmCcm>jQ!fmMd4(P|X;JIsu&6>(6N ziV57W`bT$6=0ux#m*-_g4^>1PC9PXE^FZFQ(y<-Z2ezWa~ z-FHr^ljDDS3)9jwDnn$U)YIX;jcQC> znaHTpzb1A`B^Jpmuf}M3z?C$qi7qZK+p} z2F~yQK4XwmI=+gb5!!*WQ1Zqe6pw(9y+1!?_c`|((!dmK$4@H_!alFl=k6DGX)isQ zeZ~Gl@Nni;$cg=l3_RuV>^8n0yMT45M>Oa0JNPjQi*H|{pPZHEBk%*Zf^q5u6*!Eq zFn_Bm+$~7mS&2dkx=+W%V7K69}sYvfqEfeNPCw zw}H*EgV+(2W7<)6iRJbg=@^qcRa`!u;F7m)nK}9vjTPxLTx3-q%8C0zb&*&(Pq&sXp=n+(qRk; zNKBY0*+Erw0O0yMC%|3L0|{1sm8w0^0JF~ke$i`g^0~sqd6N#u$xW|^gSD31FSZ&F zFvG77EN>`R^f}wkqt%tCrxVLXxwPu6DGLSEK>BnmQy!~Brt7w(2(_^V1Qmob33+rU zPA5_;%IQTKGg5tmqD<11iIVZNJ4z~Y>ebt7qd!djP?r0Dls$%vUK)XXNRpbInz@U6 z@XxhWa^()^)L>EOu}cLd6gpt$`xI)KE&f!l>>i*3G%13jNrGBL=juQ&Ap?kK4Iq43 zu+2qqv)a+m{QZZFo4i5GRruUCCsA-Q+ctiI=?>!=<_ki2)#>;1fle?HTI5WaF^yAX z@7r*K!EF<47}KHA8A;rEegPF$e4J#TFMDZv#JZ( zX!M-3PKR(*XcG_+s!pSAEaqD&id?eCB7A>yQdWj?9q%wbnT>2aL0!;b&GKh$p@JHc z5-R|x&Q=i3U14Esgz;Q(9Nrh|{!j&G7yo2O+l6};RA37o(&)JeMPK;95_V@O+k6&>7yI23+>?rszTNoff|T3Q+e zky5_R^_;65J@@^_M<4WYetXTDHEY(MSX%+^lm_B>ojt94Y(%UT)4Ep@<3$)0W`ztC zPM<4lReNeJmn8@ z#PLGl5ro9p+Rd^Va?|ZkiDgu6kx#qofSlHdI);h-^tsO!3r%IZWJJ$*1P#0>ofb$0 zC&EH!K>ot1#tbzg=Tnl7jd_dIiig)TT(lr=+PDzzYnVba=C`%^SH6?d+Nv#OUY^r< z(^T)ueRvA|zk~B{;q{hkbvl3E#v9b#xkH>$wxMb_SXr-?@CvCrMj=HSx~$8zh-hV2 zEngxo&T}@MXCK$aerysysm1~)lg}t0lLW4F62)%MfLB`1(CPL)rp2c$-jyF^GvDoe zNiutofQ0Jyx_DLM`qAF*(;gQr5WJP?nSET<>AIy=7k}TkI0YQ6ZcAOpFF0RQ792b_C$hfkQ=Oz zU<>&WWZuDK)455ZcI}?}T*?xD&jlLRI(_aEnHmBV<|r9!mInhQh2H5`1H2ItJ-(apfZs za2wPul(jz~N-A zgJ0I6TN-M?wlMHhL(s*3hFoMH3gwpg&P`<@6NHnndhL`PC>)CoEVVaP_WCc8Zk4*z z*(a-bajhekgFW)sfWFLr%zR1&)_Z*?>=|^b$m*PQ3tu>9FOp78cECu+uO#t7L*m0G ziP}l~`S7(X=w`n!$m{gJ>U zGr|``6dmNqX!1f*RA|KDpTj8%U8=~ z8V7x+&|JM1RJkbTvY)}g;7+?Qmfd7^K58#lJc}JyuM#}&=BvtT%A+wgo7ZfaZa%Mv z6Is?yXS2ZKBHCh6nm(n&@!UgKf7yIsUamUvrr5p3A~UgWeQa6#CM+iGCFfT9XWrB% z(|Om0rflzC=?ks;YYC2~4{`ILl3nTgY}eU~qO45znV9NysR8@9Gh9@MZJ$$l4ZMm; zSaWX8lh2xr`Rw$f6b4?-&mbRgvMzV@gcXIA_nyy{&mlquD_4$iX4z&;xk$)XS>px0 zX0Y<8w#`$Js9yY}}7U7f+4#=UbW~CN|YZA|F)3LPuml#W(OUWb6|yOuh;U?*0afn`HlxvYXm(E~Vw@Tc zEN!u}gb1|JJj2s27^h5$%XET6IL1V^J0Lg3d6w9R*5>g3l*0D~BaRcQl}?+TS^t>f zS32HK+PQ4Y`Kvt6h0~G#;KkD~U`N>SGma(EXdVsS$*iW&AHi%a^B%o<&7V!(=pW;B zjr~2wUp?sN)Cdg8GTo1HsA_{G)K;RxC@2!eLW@H!ZdEZVf;T1U3iVU#LClNoK2wx7 z80Eo;+Mt`vpsL8hv*abC z4?}Vh_`W)W{`|dXy&JsrDA$2;y#<7<7uczV^brgT3Nq(@+Bw}^>UWQ^Wfp2`21)bY z+ik4+7JFV5#AWFTXuUP?;>+78n>jb4H^#LpXS8LsI*kk^rJY24;x(@(ehng^5_>5o zUCSbFkbW8!r-{J^yEP7iZmyQ=JWM_zNIHHxcZzFZ@mYzvJyV9m6vh6W&UlYWJWY;4 z0l{xt3zBTZ{aTuAek>z_^F>9KeQ@^l1ZM?q$@o`0iI*d;X^(bG^jJ72%{U3zm>ShE z1S$o`v2N7t>h0K;vzS?NlFPqJM#aYQ$#0XzzX(xyc?sDf+`=`UQ3U0ZMJgXxD9Ib7 z)0kh8s4o$Fpl_X(lxCrr*K8$I8e^kz*Yh&Vrp361Zsujuo$Y|NLGb|Ukvd&~xziWH zj$4R>w_uD>=vzu?UNCEi;t&y=%uFg-qJDjuz2NgY=;d#Xor=~$^kc?eMZDoD=mrcu zY1{A6BRe8W{HunH^^2~lbzDC59gZ#1LDx})S7)`3`1&9cOwa|?tThTRpPF1V2Xl{Z zGHg%YU7a@*Hr9hRYrWkerC$qoM#D4}u+W{?1kN2JrEch0Ytot7`99(U!p$4Lo~JQ_3guu@hQn=6ymERkJ&GUuj(_RQzR3gTnNH0FH3oen@~8U zw%bH{WN4nN$ok@A9`@SdV;=OvBaW0_VRpu;cxYf9_QK9DKE0LaW*SINy&k!J|N8NS zpcv(FZZ*H1$J5TXcx9!PmD%xn(~M*4&TaeU_bcJ$!KvXxReWJLm&^Q?uHsJqItIQ; zmhx0JM99IRomEBAOOx@(99wLbL}c&cJ23)O3-d>=$4_~vy|{*4khZ>>APzDg z6^_1mxb3y=83}$X&mYIRvJ|L`(1D9Kv{Zxoac9QXO^2liBQptBugMd zNo!;lh{q};d8QC_%r5hKtN8YbV4XkmOAEautI8*@o~Nwvi``tEi7RQ1-(`f_xz!qn zuWLu_%Zrq+d`p)?4j@+tsS@Gp>o6oACMe5eD!6N_k%{<~sd$qFkMc|uuY?Hi>!@Wn zy#<-ZzH8$C4k=T_{~kWC>qzQRKVqt)^mpX0C$5}#to(1*&&Z=ERMVpcDQ~95PH|E* zETn_6()V}@ScD+s*J$xAXmdZ#9ahRs&(&oPdD5*=em_Ru@d(E#S>b;Py6xjHL2Zo^ zIBAp7!;6mYS{eGmY%+ysg4_WNuvg7kN zSD_2suOB2eSq7B=1FEK39NEuBaF6;4LB_B>;fn^qJooK%NPU!QF#$eM= zW49|GF@Q?xjvVPJ_O`OE$C0m(V!h+{8A5yU7H^{6(q;n~T4Zk|o)xeKj(=}bxVV~0Aup7ID*X>em z;kShv2K_dH48!onTnoWRe+(I_c5=*E+$2$WzqH+0@O}*jd=w+4!%N zyKXA_ifGEn0<8>oG||LF7{Y>L-FCtiK}7F##GjPBl#$EC^>wz=)S}mKSS~nmkn=qk zMoq|zL=wC%jM=eI6QMCr&TjWGAJ5|P_kFeUd%X zhn7w}5urR6)zwKfiq{=ETH1^3uyI13ixuf{Rw+IuJYrG^di@O>1V8UpKMRn( zBY$VW9W6mU*6)mGW!^6h+hjiWrQt};PBibU9(T$J#q=ml$!NoF5fr#JWooH*Q6HeukT6`()T;vGkh=34T1#=}kVk<>s-9^H2Pnc%p(*6TA?LK`adUn=b0R_uq6P=>O_L7FmuPkZgmkju-A0%e+#*>MW^=VS zs`BaP-FRC9-kSg_hYQb($+*6FN1mgnV)3`)8xY~2qVL3jyYMJA1SXcbJpM5!tH%Z7 z_4ZK&C6OHQ_T(%v=<{HcxP%f;5RR`|G@isvYg*dW!|1%RPm;uDriM1@rmS*Qb+7)d zz3iucRxg2Gcvh`$myVAfyuli|!o7a{C+6I-@-wDLIGHZ5F1;V`y08iOrCDu_Ch~r% zb)yKj-)vs2FOlop=U#DCosO#9FlO{hH;%j_D0kRFKC?jXm5(q+nhbBc2{_oj+x*W8 z8caLUlXpPsGA`h~?B7?=9-IqS1v$Ba>`g%mZgwVrzm$cl2rB}K_`a7cyU!OhFjUWI zSViI5(bVN(BjHMuC%r?L?qgrucIE3fc?EYk`*A4w?pg91HY!AeKFf8a6Uj)2(vg?X z2A0iMI=CD19D&AZuY^fnHPuHlE+-9YcL;Ksb=A z)v_fBiqNQ#hX&1C!4W8%p-PeVGtbu98urnx>^%uP4Kw|$ko=W?;%ji!E7LDHu(1K? zC+Wf**++!O%Fb0PwVM09uxQrDPilPf~I>xjmbsF zT0=(KXSqRm))m&=Ztw`h=KjD}d&?TMmFl?9I@jR6OSJ0wIp(7U($79JLz$d3QuutbP@=kT0>!XjzeKe>w_T>7j=Y!;Sxr7g#rbIFUe0b2I(e|C;62i4<0@ysgp+;{zv z6IJ1!R38OmX`9_}aWYH^8~e;dTxY-uniCMA5=XIz+QOv`2V9sWIQ2>6dgGNitU=OU zDjS9G%%;kuY`YplY>mD!CEz}?4xuBdm9y9lNSH42d&0w%i(5>y%F^f+)qa}D#B312 z-G1(`L0%*|ej;>)8StOnQTTlI6*2#3M!vt3#Qc5K4>;`(GB%SiHoZ?z{MTxOs?EJ& z3ru6CGQ!R1C{a^0Il(=zcved~OqNawh4zN>TbnHvs6IOhq_NQ@BDK&*>CbU0iE}*4 z$qyMT-_q!EEU=T)ZgH_w>#+KW-gsIl#F)G6tse1foul6Em6gDW?BUdnVcl255|N)FKgw)TxZ6Cj>`GSC+wGd<1_9bD@GZOFjt;}zpCm(z>XrWlc>{2 zfz)BDqP3M|JUV{6Aw~H`n(h2hX7F3vA-)@KAJiQ_ChG_H)1HK{fyfo)x$WribZ5{d zwdq)4@^Z!!Fg{XLFJDxc5sMB*&(xd?DC;A2=!D(~q?08}d2y1DX4ECB$H1{yj{tcy zFK0rCv^`^}*aZ~Z1Z$IVYzjVW$cJRnQO8lhjd;osa!X3;y_1$43bt`2!0-z7v|ocV znBqu?Wgbdss1^OZH%f|BN`}DHNlaQ2ruHmk{ZaKT0CBrTZ{2y{0dKsyt7j9`(?@N}XwwmVlN`_&0Z@G#n~D<@ML4Heyr9>S}N}e`H-=>k|md1}uH# zf99S9;+~)PKh%LsAU~`-MMK{MZ4P63?i$;QA9_(sL2dDQiFPFY;sJxl9P$EcspVd>!}wJa70Ey6*9@jU|dD9q4u~$zdl<@uYx+`kntc zzXRfq92K9h?P*rZ1r)dooFr5q%C%yf!Xy_#z{+S!74ppSkb5Aqeoki5wAp3%Y7KRx z(4`fS3yB3<>U;tYl4>cYnCzJX1dzAK$Y$8Rs<8OBV2gkY%OzFFVpu-2-D|pWtIZnz zTGn0JyOxZPwvNK)3XNi-5&y0&yLE-eNub%;2Q>NMaNAu{ zWSgkTI@!GAH=~zP4g}}?E?ZhdwO608g-gdZ<}26AC7i!7Ltm_o&?m?l!f-GM-yp=$ zx=ePON%v|Z#H`_{y!<%dNpETLGQdCqpPe}lW^d;e#tOK8WXZhkDFc%OU&*mInrz9S z1Q~tZrv@g$TyINU$Y}Pv>4O!XRXL`Kbg1`QxGMWTMZ?7D?r?PAe3{YuY&E)t0S3JX z5V2}aI*&wc-se_rIzg~;lQ4h2gM8{NbClya$>3#GfpsAtKSup-c}d{e6XJa!tJIF} za{(uBJ&kSn&cZbwnI(8iSuBkKDFVBc_1Z0qt0YjJ_l!Gwh>4pg*2P zP($F4Kc9of#&qnqF%0kdx*X8!d{1bRR=te&4n@VI2QkwA1{l z&yYi0xYists0kd+?fP0=R~k0%mlNgRd_Sbtww3u79zHj?1dopdTa{smAPZrZ%)k}r zo}JXe!`pjttZcAog|n@HLMXE$JQzLs%%mYKg0*;%lPu<`gOD5tapwp4(@TjyTZnZS z{-M&4^G&_3o}&WsYpWsmZ;a4_AHWPPk;QuzXtiM2n`qt{S|)|Q%y{~Eo+lT7@9;S?&ra(_>WVp1`L#-2e zO9&9XyA5B>vewNYqRLBmo5N(S6Yu`-#`10CnveZQ!40-)nev0Fbn!Jm7&EyXVH|98 z5)M|5-f;B$$-rb+I4P>PkCZA)SSc&w3=?jCVjf8>W+li>8x*wK>6Hp1$9{xZDMc30B^+_du3arc7I>Jiq_dh@q8o^>&E!L9RMhh(7Ji_JXt zC4Mg+;%jI@f1kr#+x^w|y4NgM?*m(LE(tidUw!KHv7K0L^t*dj%1zjN6Lp?5JXJMk z=Y|=Jl1x$0+42QsqD#Ha{0*e*umkgj&=j%~f$$POdq%TY-HAxx;7IXB+DCAe>i2ix z_wV`CGbBr+&|qMTe|?eX&z~T8a30{V9VQ7Y+rJK1xdGY5^wcrFJFvdsV)K$t9-5NF zN>62gkq^SqO)n`%u-Xl=ZL%T>(V=8x8nUt27|W!`n1>7{mDMgL)@p`))Q`y<38{N^ z3n|=1Th>-r7C~3mMn`(utp0G?ERh?K~OY`e_{@e7ZM1?ME5Qfjo290eDrR%Tkz3QyA2x>Q~^w zfnkos3#)bS+0QNSaL1XOq(+;_;kbM2jfk`C7jH}?$c0)e*fYx!G7%1kq-xD=8zkP^ zI?NQlY**;k^eeEvi!4H;;aG&S-5C_gfV-krSB7jA@^>3^r?M=Dg+iRKP*VnbWvgE9 zSYj2e*7niS7)C**?zxL|W%;_9CzQ+$2b=tbB$_!fZc$`(h0S)OJY$`nIEh+&cR8&> z@2(zy{tLT6V}Ya?TUK!4-E;HThFoau1q)1e+V3hPo12P&Pr#iQzEZz-_33^GdMeuV z0)qDit**-Uc_CwkQfYyKcOOoS_|5tEqI~K8ag|e&Ds-i`=GXO*TamKa+<2Af zz9FQtNGejgTRjP~|X}=u9Z-IS^FhVJK0sqNcPY=X1T$&E){wqsNC7K>*CENn_ z_h%7vcWfJI!2clUoa)@S|%XWLr^{Aa@Xuoo`G9Nw9nq@3?d*ZqMA~nY? zF^b`X%$(Wnp#BKd#rdWkZOev9ph?D7{6I2gc(ah$XW&EV=c5I+iTum7jN(XNWBCcB z*`lr1;8iccvg;xEFnrbW$Ym1~L(0X~^y0uy(PUL7qndKOtMZd&6rAXusGRG;Wh8lX z7vUf}GAZs2iEJPqV;)8or84sjElLK>g&Lg8t|B-_>MeHakAEmO;p!Ph3G~#94vW~j zLUAr2v?+=xi^5(9M`TMSB*(8*G+Wby=mUqSpbvjTo1~&j!6QZc|E(g@8oUX=ajIIjL`}*u!#yAa=*Y%c&@9y zL`f5RD#V&!9NJcgT9WNoDkFJ9FVeM96YcO14|(xZ2~$Y80(sI@v^AD(}#=4)_NDRvvSB1WIZ-aP({ z=VLe4i{W$+LUYQu22_h=jQD+IsD6efDz)}wITD*Ro^nP*==C)7bEP;s)R|9-D2&!T z(G3$ta?*!Tv!2oow{aojo0N^lh6zc9i4=-`N=DsObP_KxHlXH9AT68q@}Vf%qc9s# z_eD@ty)&9(PH%d79x+=I-rGP~ciG%_0v|_v=}pJ%JD#D;&sVzH zQnEFbad`2iwL1K^v9@dZx+ic4Th#>~K0RZCZe*nu^vG8j+RG)b%;h8B%*3L3sEnux z+^o;x{%cj|uE9d6LDy;AM6V+X3?^A$UQ`HaHgvownRO)f+b6Y3i1~HzH(A2GDAT3V zwsEF2Uzrb7S>8p$@8yn5KYfvxbn1j$Tj4nt6>pS|q4EarIS-qgEUWd@4qkY$j-G}X zmcbwsIiWv|jZ*4p%_A~S@{yv@YD0MtwvBB@CJHK!G*;d4QgH}dkcL+hRfzVNC{Zt7 zisw7DNUWhdv|y|U(;%+e(n!MChHA+hld1M=!Z8O9xY2YRBXCS;6tW@Pmb!Thg5xL) zNkpePtYm+OY^I~4g8IIuP?yvGFP>FNJLA4|i;FSO(`U$0pwK65nzxhWozmDqR>i3u`mZy?u{yYzv59V1aA zNe)8puh1fvN#9<76fDg?Myiyp>WG*j+a}&lI*h%@X8OIX{L2|JC9N1m>s!>rG_AMV z0w6?8^@{|bRDz-HH{|FUJjn!SjJW(3 zuMYYwMo^sIBZ3X`Xr6NGro*|Rl@a^v?3_UWf7j3IIi|L)x2QwS{C5ujkZ$8Mb z61&UjNfRfT@Nh=IQ`Jo4sW?hF+&x=dkdWsIB9>zAynx}c$NEOi_vQ5f&V@nvf5%aIJ+Z=ZpVvK7HmY$RmwjgBoF zpcL%rFUI;E=Ykyf()W^i z+zXL*bwi5{_J*6YiEv<`BV36$aBSJ4K_Dzu8C~Z!OH*@o9t_BrR^^jkqKGD+VcMl_ zxYInO_p9Z6mUAapV_0w4MD!Xd4`@HAoS?$ttqE>lcTRik!IUdPpH9{|8-6HT8uH009W!Otwi0^hVUdY@lBMS+oz#D`+bvt_E?!-J<2Cs`3B4XSV9 za6YVQ4!qcg{wUSLjm}?M}^X=9UHavq{BC1RkBW!KaQ@Stxbl1 z5%5;k--Za=9z+IY77ji7I#$=Y88w61OJduplYB|ngG-d`cmGBgz-1FywySQQ^JE`at7KAj~w|o{!ouG z-n5W@&Q7i?875qD?V*8%Oa|xM)%#K+_sE22?D_LJ)-_9dwDA^Jb;P6X?9KM*7l-y$0|HvXHxax(8rB&Hw!%u;C@oN1M{s=-VDal_QUpk< zQp>KM-iOhAev)-}z;>C>|J*L4_;pR`K4sf|3{9?bzdPXKs^VsE|KH64AfmqeEa5>XLRRatz(J)ccJZSUSYZi^%YrGrc-i2((R z!4p#OOe8;3NTwb3$%;<@;A5r^ralM^@%5XD1IkxcK{xz-gI@#gzILsC8yh+1cY^G8 zo-FF7a5UjH=O|_%TbZe*GO>wi>-2o>FRjB>{bg57M3Kf3?z!D$iSm{+bL26wiR$A$MmnkY%*K5ArAesv2ZC*1Lpd{vmyHtoChz&8$CQ(wu+eLBA zO^Mlkq?RWmOriKf%v(c`O&;TYIzt}(r&(URh%!1GGJ<6OWsN9HUGOJskWem9K$Plg zqy7Br`FU|wE3wUkvQeY9a8Ex$V8HrLVM~a3s4aigV*8L7V|_}<0DAkCe$q!rW6tOh zeP7%goVrJv7PEl<8ASwj8Ae&oN*wK8om!qA?iF|VGiES@;7&c4OG0_+N3 zYn3%gA;K?&7{~oI>?!5C*$arK)B;VE#o`QPFSP97u~Vf>XIjL)H*3C@Q@^1{tr8AC zha$M6g5EtXP~*+d(>A(L+h{3?^^{Y*a>V7(ucR=E2?=x@o+mm|qzLbMRMm$wMNNcU zmN72CzW9P$R=83~I#67_YG5Ax(L$Lnmpm<5HQ@{9SE8mxS;3r8Hc;jmHD#8A?M2Ra z);%n!8K4nv5;{|@eECLS-$j9F+zn zy3vovnJ~MFTd0{~E2hJQbFftFF`OR73u>V<))lbQ+`tSnwfWp-P3X8StS zyGX8g{ggo&Ls|7{i)m>P!D#wMk9vPGYfg%tcLkHx-qbA>)Cr2O+#AWEr;)V`#=GwG zTJdyd^eytb?i%Z~yLbAkO9onUB~Gu9G#d%SzFl$)=6_rOA8|cqXUL8^dP7yN$T|kD zyY-~N?-e!04joYqR{C6~>S2##5C$v$92&%|5qF8U4%^wTgs;q-l`JYain7ZlcovXW z(t0G=;ROyxZvPnkPC6mTcpE}~3DfH9+U$#oq%Lzl4~OL0Hhm*T0-nOpu!2;1+b2>^ zu!4q`LAJO{fv?P1+W7XZ!Up`a)_Py_6C*`+Y!62e+8{C|0$(~=%H7A;&*1pfn`Y_c zvnz~&v^LW4XyN2gK@5t>oK`-?8aHiErSXuvY+adufc!n$6muzKTKWRn>*_~l%oRo< zlsT07YW()St2wN|{(4+FcMPk_^@f!Tb2k`w!8#30DSw7S@p(w|8|*2*SkEQqt@epB zPt1u^JqBD*u}+7ak+hv;=cx|m3M?znRN==fJ&f^&Z3-1I$*qoW)?X3BM0I(wFOHw^h*rC50LA7+vX2>NEq7j?gd>BXNhHBKgmmxN zi^5*S`nk?txx}*)-+0k>GYT}97jD;w=$_*kb#BnQWiH5z;b z`o=fmT~ms&$}XAgBdh8iGy?jdLF2SklM5Yh>uQqxgXh)jxwPLyTeBXOFNV=Vj)`AHIfP3y-?n&s z1?7D>C|W&KF^Y!3Jqi=J=om-)k`%nj@{N)Wiw$K9RES|2yuES{3)QO50q@YEGp9{r zW9dj9@L^e-oQ6$>IYMnkvmN8`jUxj@lA6xW$j|)6cl9-O-3k5VvX%qZZ!7x7sTVFC zEHb{b!Dma)F%Zok!?`4@+-y-}?xmB|>lWc@wU}u(H=)0hOcY3KQ-!x9Y{-Z>CqT=C zI~*IMXnDcYxX4yT8WdGV=QtjMfRnmBK=BMYd?A-_FU94~nL&vc!>d=le6p0Ba>PWPI_l!t}c*tNIC7 zJI$I*rM}XSRxwSK-7TKdByo1xLq_jQIDICWnPU(L8F)FUbUbFHtv^XZpZlC6eCnCL zm?spKe{oPYx@L?CRUFG-}96lmP z2~-d+8^X4W;R-a~kZBw~(F*E_M)q&IP_7;4_Yy1 zeF%esee|=RlIZtqWqv=f#z99{)wfTBu&8N;+zb38dxBQi?c4L8GoiVESAbrndX4(D zigBf}8TF~maDbbYTVy9ydjtRDb@f56FC1Gqw_>E-AFd-wL^YJNA|Nhml@OgL>$MqCy`ChS^< zpgm$8jFBekL2+Y z(@dE%oY2Pm$3FEi-1fC$U>OrZJK}{o@-c37G(}HvIbyyd@>n-s>PPu#kKZfciSc#a zZHY?8v5R`clLHSaLV}-M!!g5Zjk_84aX*iznya(@UJuD+bWDV?THk3~8>C{yGB({6OHFW@j8wsM~++QX_gI2F5YDaxTHSbX-6d%Qyb$zbd7L_S?Ovp>l-}@ z&Tpx0sgc?RYW{mKt?R=h^t6t2$cM!fuDM=qN5U!(sU119z)77c4YG-IDErhyMT^Hi zVNoZ-d|VbNcWY{r#vSM@cws0yigET43$%{UVwe>H=JA@OXOpfZl_?6!mo{I4D>~Gd zwpc^ApR^u(t51(q0hLNLf}-yd);xB@)f4>*)UC`ob%Dm(931~KvB}d~bPfmOH;Y;a zgoElzrOcoAT5>PwxcA&4FgDJGKQ6bmk&|weiS)m61_f+F4Oq2%q|r?1Q{#l7AJZ7W zWk{K%+!Kd5RzO%9H#)gPx(`~lB}Vs6fS|Px^?#jY!TM9s`qx&!hLx6{CXW9xyMs88nPK=3#@kVdm%eI1<>=T{-@i>XP&AIC&0iDYR?<#EN>n z@Abx5(FI%KhMm$@l74_*TaoN$?b!bNTsz{LIG!Q=TL=a$+T-MJE zp|n_@gjYg~eh5P)=*PXVwVdT}L~F63mW~9D;}k_8(Fd!EKjsRnc!KMW`%am9)t(bs zEHJD(TSLaxBB`(khglLW$e#Bw{RK8Vfvo=yCd5j}mUUaX3qod0ON7B-)oDzj$dZjw zE9~S@k;r*d>ysO&%s5!yvW@)I9XJs; z7&^!L-i{JSjl5%4CT>)Hc=$3KI(p9@0a~6qE^eN&a&!B{&DFIdFlI~SNYm}T!{9h9 zQ;7Ex8QfYzm~PKLog~O_rf^aSO-mBWoSt&(Ttm(wnlhz6jCdyZE|;V!Pkj&tVKKF5 zcs44Kv&rVkOBj-=23o!fXg7RQ=h@B10>!M6Cv*EF%v1_bBqvGoJ0r8gHN9$ZmqHlN zKYf~2aw6lf%)=UdA(5Z@B5-O8CxH;OfJffquhM8T(wJ0Wr;^mo3X_jSMP4O56tENJ zcnIf3_BHXY_;m;8uABlWxz)w*f+mpw64%|eCRvywZ^i6!wV8OZqMXcYH+~lvmoAHe zarYOy{o^tjm?($v@l~oZ@J!D&-9cQjIM{=b(ad(dHJ^s;EuYj@c8+HdX_djQ(I@e8 z3r3|u7SJfhjO56@nN=z~aEVQjRu(05~U8SL6b7-=h#%0dt&pS3B(B@lI z5=Kj~!Qr`C{%)r1A`P?fwS26`HITB5uqWKr*Rg(6gOugO*f%64H&r%r#!U+J z63*1!TV{RIkvJ<}8e!p9Q*l7n0#o$4+jl4TH|yrPFQOKQ%;VtZQmjLPi}=)dSH`|N z4c~DPZss^TP$Qq;Wd%-bz|jjMc95Y_?mVJ1H}qdp7D&~1OUcf9f|S9uKEm5swAO+E zMfU+xpC1ds7s_zU?8wH(USN58nP>DJmwSELQ2i}+Xa2_iLHHI5&Lw4MKc;-dOdD6e z!eSh9$*DfU>SUdd=puAy_^~R5m9tVyxC643|e<_ z^mOyr41d}jg$XNErtv|UgXa&;b@tO!XwqLxOto~yd4`eCA8YvO@@k#tRRuo6E$YO( z&rpL&XZjO5xX*REI8X36=m$`7(xhQx%4t^{8ZhVAS~7D-Dx%DGt+fGTW=~$Y0-95_L3r$ zPOqVh(3wbqfYQt=_#hda)p3$9X7K7#gOthS_I-P=^4lFs|1ZitR32oF%%o5*AH1RX zNMF_DohMB(s%AVAT)eUkeY4Syt-REelC3R&&{Mr9lJG^0anp_7;!fcU0;E;IMAA@# z%3;BfJ!tqX?3SFBv&atoZ8YoDx6`-q7f^(~`;26_@bH2=j*hruzLGoqd*PL2@rACK z4hOv4!C^;-Z61hYdJ8P^g}oe&5rTmVL?u|?h1WXQ_O#*o#UDSCa6uO}lL?AKPBkNc z_K4Lj$Osx`z^@|$fh{gM#y?`pVSpt|CGR+>1BPHCa3wVOIiGZ;@j?HSE#DdX;sagF zJ8Yh(v8~Q?MF;kfGP; zO`)OMd>6-)WtA~da>P>v;o`WHkFd%cJ#>_T({YH(0au@5r43(~lo|-rBiNe_`8BEI zQ)#+X=A-P5>iIX1+D3xlHVE1bLFP|ahPbTi^@`^u<@G~1cMOn^Nn!jkmfSBfKh4x` zJo;`SI<-4Lw9_O3BBFj7tLc-W;00Y3%-E?X_JuKtcw?`-(|FSr%YV~$Pd_BIpx~kp{6ht zo&1puRV&kF^Y}3s*f`>S%t9qh-Bad3o;EdFL3y95v|++R*a2Ln!5Jt*?xYQhZC z3KC56!V1z7;;L$l@)F;Ne^6k-fG`BeG3aah@Ma@$#P*jG1N^K8tds$%34cELzKV?V z-lYI=qN^Ur(2Ds>1u(GMzpLEW12(RIZd(77A#E`86%Jqs0gU^Q=VxIC{^dW9z5nCy zRl6Sn&_5v-{nNerz<<{V1jqPE0DgJ~{L6nKqPA8b`@ix7{}aJY@9dZkAbNoc59J^R zuI&F8p$c+#2RW0o{8^3yVTZG1pfS=wCp?tn8?ev+56Dl%|6eyuBY}ZgyO}xu)(z@q zLErI!M7gQJ?}y!R@plzbV^d3zs)MNw=wF)8SZu>c4cM0gAm{z z(3S31rl9|$Grc{$^J0IX9H+P1z&|V zzi|Xf|Hxtevpg70#I{a<YBJpjTD%XL(Gh{>b6@ zGsia=5?>Gj3=9o0pZk*nl1&(I;R$J+vWD;lD_~Wa|)hF#Cfonj}ff zN+hSN{~dL?{7xAKC=iPy zUYCF*M1cAp8uw(?FO>VZ=dT#>51{F6z?@b;f4{edX#hm>i!Q*xQ0smH{StiuD z6JQ_VfT=yymsRh-pneDW0E!<=*kLjS^d$+%^l)Zd8~g=yulWDbh45S8b3UmD#*pf%Ha>bQ39Cc9qoystANg#1v-cLR~f)+*M2~NT*-^;lMsuKHYQHti_2>uX zhoAk|hTZEE$DYa#3h3f#pke3_8b);W19ES0|K{^)tz~3Ydmu-7fU(pFsOO=6&AmD{Xkg}eXs(keKR`fV|9`OVg>sO!Ulsrq z!vPG(hjW=f!B5tIUSa>FntMc$WaEY=(9PjMeW0g*Dc_0zf%v^W_kgu0!*BHf#pnWx zc?d|Q`!C>r@claG{+?Lw0Xt-kOP9cN{Q$^A8)0Mk0r=sR?%$&SEJCtopG7pFh6cdO z9y$^`#{Y_-=;r$0@$)+-EKo+aaN0yT55NQin1|YY%KBf-y>tBY8{a)bs^ai85D?hzqiyHs7JkaARBl}V6F#Z#u&HE*ShXeQ8>c1FZ zdInkj%j(EI#EhDv_6&$xj5+_=B~-wRtecrD6EIl*hWym%zqxcklwXQ|F+@k zZ1EZ`V9KmL9se^bTz-2xV;AJn{iJ^j z$V>i9Js^OKd00~(m{owlTg=%3SZDdq*|eXs{5r;ts9n~u0JGi&-nIcB_)E!5ct{jB zwXt{bumzb}fb9NtyOy>$cW}1*C3)sQ z1y%Of?{NTV&c96oFH0U0WkDcEVOv1bKljG_68LdcKz$~FSv-uzoXZ}9?kD;G zgnW|#k=g-~9tQX0)elLkmTs_LBh{P&-F6N)c{x!2nQpf{EW(%tnvMEzy1KRSZ^!Qa%p9REd9 zqa==tbU=^yxw#*XSgoP|f&Xd0|K?Hwhw@7inD_y6{>!ib=Gu0!(9`_@BWngag8G+= zU|^R2topZGmveA&k^6szoxMu~K@i1H(ZGh=^#T;1}44jfKS7yFK^4xjntq_siSax$N9t?v1o)8<*V< zYh0j%*O*yaugN@^TBwJpBUeh0q)M{Uo91=zJic5Ct0oc460dZvc+oUinCiYAntWH>@-jybc%M zA{B9eZk-0$<(o_OiaN8nx-h?HqwG}R^kXYazJHkhWECOH49tPjh9k=_9QAJtiuz#k zgEwrA$UjxDc$%*-rVb0X8ta4a4}y;-C~&>S{=eX`Z2+%7?`^GM?vU(Qrp2LaHg8j{ zbOK2=9nchXbLDmQJOdQi!FQ7t&${t`MQ<)1SEUO$HgnJkRx3g;BPKm(f#h-a(j>Hx z;Y?_elGoJKp=FHE2}z^SpM$T{n|?q^jqY)u(J*|!nQvU`d4&BMd}si^*};=`F$4e` zY_mU=oHSDm;h*g|zcXXNF_)-;_}&W9((qY4-wZWM9%QVmT}pPTH|29I;cZUJ@)7(1 DI0-xr literal 0 HcmV?d00001 diff --git a/sendFile.bat b/sendFile.bat new file mode 100644 index 0000000..88633ba --- /dev/null +++ b/sendFile.bat @@ -0,0 +1 @@ +java -jar sendFile.jar \ No newline at end of file diff --git a/sendFile.jar b/sendFile.jar new file mode 100644 index 0000000000000000000000000000000000000000..72829a349f0c4e4f99720d4c9b919816d3c256ab GIT binary patch literal 153757 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 z%0A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 z%0A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 literal 0 HcmV?d00001 diff --git "a/\346\233\264\346\226\260\350\257\264\346\230\216.txt" "b/\346\233\264\346\226\260\350\257\264\346\230\216.txt" index 6788c52..11dfe7c 100644 --- "a/\346\233\264\346\226\260\350\257\264\346\230\216.txt" +++ "b/\346\233\264\346\226\260\350\257\264\346\230\216.txt" @@ -1 +1,24 @@ -1.数据库操作 \ No newline at end of file +一.源码修改 +2017.10.11 +1.修改初始seqNo重置 +2.修改Acknowledgment2实现getAdditionalInfo方法 +3.修改UDTSender接收ack,最大值可能不正确 +4.修改接收UDTInputStream添加hasData及方法,判断数据接收 +5.UDTInputStream添加大数据接收方法接口resetBufMaster,setLargeRead,因为数据会覆盖(再读取慢时) +6.修改UDTSender添加数据判断,数据全部发送则返回true,f否则false +7.UDTClient修改,添加close字段及线程字段,添加close方法等待10s数据发送,原方法shutdown保留,直接立即关闭 +2.封装代码 + +1.SocketManager不再使用,外部使用不在管理,需要自己使用完成后关闭 + +2.judpClient封装UDTClient数据发送端 + +3.judpServer封装UDTServerSocket数据接收端 + +4.judpSocket封装UDTServerSocket返回的udtsocket + +5.RecviceFiles封装文件接收,按照封装代码重新编写(源码文件接收没有动) + +6.SendFiles封装文件发送,按照封装代码重新编写(源码文件发送没有动) + +
  • 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