tag:blogger.com,1999:blog-32335031260019050872024-03-13T17:23:27.868+01:00Mite MitreskiMite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comBlogger55125tag:blogger.com,1999:blog-3233503126001905087.post-11776029698085035392020-12-30T21:03:00.013+01:002021-01-11T00:12:43.621+01:00Selected podcasts from 2020 I tend to listen to a fair number of podcasts, and this year, I decided to reflect on a few episodes I really liked and opened up a new viewpoint.<div><br /><h3 style="text-align: left;">Does Advertising Actually Work? <br /> </h3><div><div class="separator" style="clear: both; text-align: center;"><a href="https://freakonomics.com/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" class="lazyload" data-original-height="52" data-original-width="228" height="50" data-src="https://freakonomics.com/wp-content/themes/freako_2.0/images/logo.png" width="217" /></a></div>Companies around the world spend more than half-a-trillion dollars each year on advertisements. This two-part podcast covers different viewpoints on how really it's worth it. The <a href="https://freakonomics.com/podcast/advertising-part-1/">first part</a> is focused on TV ads and their effectiveness and the <a href="https://freakonomics.com/podcast/advertising-part-2/">second part</a> is around digital ads. Considering this year, we had the <a href="https://www.youtube.com/watch?v=uaaC57tcci0">Social Dilemma</a> where there was a strong criticism on the "Big Tech" companies around having a strong impact by targeting and changing people's opinions. This takes a quite different angle around how little ads are actually effective or effectively used at a large scale.</div><div><h3 style="text-align: left;"><a href="https://freakonomics.com/podcast/urban-flight-part-1/">Is New York City Over? </a></h3><div><br />The covid pandemic has hit the world's biggest city particularly hard. Due to the rise of remote work, many folks decided to move out of the big city. Does that mean cities like New York are dead? On the <a href="https://freakonomics.com/podcast/urban-flight-part-1/">podcast</a>, the hosts look at the history to show why that’s probably not the case.</div><div><br /></div><h3 style="text-align: left;"><a href="https://changelog.com/podcast/418">Maintaining the massive success of Envoy</a>.</h3><div class="separator" style="clear: both; text-align: left;"><a href="https://changelog.com/subscribe" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="the changelog" class="lazyload" data-original-height="410" data-original-width="248" height="240" data-src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF0NXpYGSIaU1mjUwzr-FpeM9gro5JYRuDY6Ttj-JY9IecXjiXENvivxSjAdtPp674n7E08YGMe2lHM-F0ZAcPejwZOzxb_GGnEPamygbhIvJZsUHlrpztU8NrcJqI5E4SPjG9PFYdGIs/" width="145" /></a></div><br />This episode of the changelog is with <a href="https://medium.com/@mattklein123"> Matt Klein</a> as part of their Maintainer Spotlight Series. The episode covers how <a href="https://www.envoyproxy.io/">Envoy</a> was born inside Lyft. Envoy is an open-source edge proxy for services designed for the cloud. In the past few years, it has gained a lot of popularity. I found it quite refreshing how the focus has been on making a shared value across companies trying to cash in on the project. I suggest listening to Matt's conversation if you wanna learn why he picked a different path for the project.<br /><h3 style="text-align: left;"><br /></h3><h3 style="text-align: left;"><br /></h3><h3 style="text-align: left;"><a href="https://mastersofscale.com/rapidresponse/">Masters of scale - Rapid response</a></h3></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5-rBvCT3rZhJhbJep0da2MLtbQmJMUam30w_FdHMbMa3-Cw8cC-0g5VNVfEmKu3NdrvqncrFV5LeXUx7GqK7rj1E2vpsQTCcD3Hu8AcxvOvSPwr2g_7V8lB1VFQjylbnP7zBM0eKH2tM/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="" class="lazyload" data-original-height="207" data-original-width="375" height="177" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5-rBvCT3rZhJhbJep0da2MLtbQmJMUam30w_FdHMbMa3-Cw8cC-0g5VNVfEmKu3NdrvqncrFV5LeXUx7GqK7rj1E2vpsQTCcD3Hu8AcxvOvSPwr2g_7V8lB1VFQjylbnP7zBM0eKH2tM/" width="320" /></a></div><br />The podcast spinoff got created next to the standard masters of scale series. As <a href="https://podcasts.apple.com/us/podcast/special-first-be-human-thoughts-on-crisis-from-reid/id1227971746?i=1000469638012">Reid Hoffman</a> said, it "A podcast to match the times." Since most of the world has been going through a crisis the past year, so is the series's focus. The series features focused interviews that bring real-time wisdom from business leaders to make quick decisions at times of crisis. The episodes were quite useful to me over the past year. </div><div> <div><h3 style="text-align: left;"><a href="https://www.npr.org/2020/11/11/933950483/worst-tariffs-ever-classic">Worst. Tariffs. Ever. </a></h3><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgT-z-FyqTVibp2ptl-k4dBZbKtuVXJoLclYcEzjGGZwC-UcPFqC5JjLzcJrDu9LTVYP-rGay_dTPG-xMPFtCp1XZl6ViYNO6ZBcYzxZCsjINJBFGtLs9FrCWzWvnIxuJO-AiLCJ7x8-Xg/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="" class="lazyload" data-original-height="121" data-original-width="600" height="65" data-src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgT-z-FyqTVibp2ptl-k4dBZbKtuVXJoLclYcEzjGGZwC-UcPFqC5JjLzcJrDu9LTVYP-rGay_dTPG-xMPFtCp1XZl6ViYNO6ZBcYzxZCsjINJBFGtLs9FrCWzWvnIxuJO-AiLCJ7x8-Xg/" width="320" /></a></div><br />This episode is part of a podcast called <a href="https://www.npr.org/sections/money/">Planet Money</a>. In a sense, I am cheating here since it originally ran in 2018, but there was an adjusted re-run today. A lot of the policy from the past year, especially from nationalists parties, has been structured around putting out Tariffs to protect local workers.</div><div>This episode goes deep into the topic of tariffs and tells the 100-year-old story of <a href="https://en.wikipedia.org/wiki/Smoot%E2%80%93Hawley_Tariff_Act">Smoot and Hawley</a>.<br />It's a fun story that goes into the topic of weaves in wool, humble buckwheat, and goldfish. </div><div><br /></div><div><h3 style="text-align: left;"><a href="https://www.npr.org/2020/03/06/812943907/episode-977-wheres-the-vaccine">Where's The Vaccine?</a></h3><div>Is another Planet Money episode from this year. I strongly believe that the right incentives can make a dramatic change. The episode goes a little more on the economic aspects of vaccines. How the market for emergency vaccines works and why we don't have vaccines for certain diseases. </div><h3 style="text-align: left;"><br /></h3><h3 style="text-align: left;"><a href="https://www.wnycstudios.org/podcasts/radiolab/articles/bobbys ">The Bobbys</a> </h3></div><div class="separator" style="clear: both; text-align: center;"><a href="https://upload.wikimedia.org/wikipedia/en/thumb/b/b8/WNYC_Radiolab_logo.svg/1280px-WNYC_Radiolab_logo.svg.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="radiolab" border="0" class="lazyload" data-original-height="600" data-original-width="800" height="217" data-src="https://upload.wikimedia.org/wikipedia/en/thumb/b/b8/WNYC_Radiolab_logo.svg/1280px-WNYC_Radiolab_logo.svg.png" width="289" /></a></div><div>Episode from one of my favorite podcasts. <a href="https://www.wnycstudios.org/podcasts/radiolab">Radiolab</a> is a radio program produced by WNYC. The show is hosted by Jad Abumrad and Robert Krulwich, and the show focuses on topics of a scientific and philosophical nature. This episode covers interesting aspects of Roberts's life as a reflection on his long and storied career in radio and television. It's a refreshing way to listen about one of the hosts I heard so many episodes on in the past years. </div></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><h3 style="text-align: left;"><a href="https://tim.blog/2020/10/14/naval/">Naval Ravikant on Happiness, Reducing Anxiety, Crypto Stablecoins, and Crypto Strategy </a></h3><div>I can't say I have a deep interest in crypto, but Naval's take on certain aspects of professional life and reduce anxiety was refreshing. <a href="https://twitter.com/naval">Naval Ravikant</a> is the co-founder and chairman of AngelList, and with that investor is many successful companies. There is a book called <a href="https://www.amazon.com/Almanack-Naval-Ravikant-Wealth-Happiness-ebook/dp/B08FF8MTM6/ref=as_li_ss_tl?&linkCode=ll1&tag=mitemitresk01-20&linkId=9d405cbc873dbf7ab55d7a44eeecbf83&language=en_US">"The Almanack of Naval Ravikant: A Guide to Wealth and Happiness"</a> that goes a bit deeper on some of the topics covered in the interview. </div><div><div></div><blockquote><div>Proper examination should ruin the life that you’re currently living. It should cause you to leave relationships. It should cause you to reestablish boundaries with family members and with colleagues. It should cause you to quit your job. . . . If it doesn’t do that, it’s not real examination. If it doesn’t come attached with destruction of your current life, then you can’t create the new life in which you will not have the anxiety.</div><div><br /></div><div><b>— Naval Ravikant</b></div></blockquote></div><div><br /></div></div>Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-47106229005509095882020-10-20T23:21:00.001+02:002020-11-10T12:47:38.526+01:00Sweden - Land of the mask-free and no lockdowns, or is it ?<p>Sweden often lands in the news as an example of lockdowns, and masks are not how to deal with Covid19. I wanted to see if some data show a bit better insight into what goes on other than looking at infections, death numbers from <a href="https://www.worldometers.info/coronavirus/">Worldometers</a>. </p><p> Since the early days of the pandemic, Google has been releasing <a href="https://google.com/covid19/mobility/">Community Mobility Reports</a>. <br /><br /></p><blockquote>As global communities respond to the COVID-19 pandemic, there has been an increasing emphasis on public health strategies, like social distancing measures, to slow the rate of transmission. In Google Maps, we use aggregated, anonymized data showing how busy certain types of places are—helping identify when a local business tends to be the most crowded. We have heard from public health officials that this same type of aggregated, anonymized data could be helpful as they make critical decisions to combat COVID-19.</blockquote><p> - Karen DeSalvo and Jen Fitzpatrick </p><p></p><p><br /><br />I looked at options to see the trend over time in lockdown countries and some great folks had made this already by storing the data into <a href="https://datastudio.google.com/reporting/a529e043-e2b9-4e6f-86c6-ec99a5d7b9a4/page/yY2MB?s=ho2bve3abdM.">data studio</a>. Without going deeper into the totals and the assumptions made by the group storing this my key highlights were the trends.</p><h4 style="text-align: left;">Stockhom and Sweden. </h4><div><p>Copule of highlights of the approach Sweden took here: </p><p>- No full lockdowns</p><p>- Small events closed down before summer </p><p>- All big events canceled or with a small audience</p><p>- Some travel restrictions and many recommendations from the government to avoid gatherings, work from home where possible, vistiations to elderly homes limitations, risk groups warnings. <br /><br />While there were some hard blocks and lockings majority of the measures have been on pragmatism and trust the citizens to follow the warnings. </p></div><div><br /></div><p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN4zFziE5Uj6QWTZvs9rFwL7wY_3os3Dr_SEzrxQW2f9aTPU0RFoSMpcBmtCmd14lwc5qauih5oIYq32f_eIiVwth7Wea-YJ9TyunKbQz8qf1GRQJKgMt2nUCK6JhGKaZdxnehLlCCDk4/" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="1182" data-original-width="2048" height="370" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN4zFziE5Uj6QWTZvs9rFwL7wY_3os3Dr_SEzrxQW2f9aTPU0RFoSMpcBmtCmd14lwc5qauih5oIYq32f_eIiVwth7Wea-YJ9TyunKbQz8qf1GRQJKgMt2nUCK6JhGKaZdxnehLlCCDk4/w640-h370/stockholm.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Stockhom trends<br /></td></tr></tbody></table><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXpXroFbEzoZaNS6aJUsXD-jqn1PvrLVArV3RfGuWwhyEwEMiAbwj6DVcOx_Bwiwor3R7-c23VXzirkYbkzE6Mj2O68rC4Z7x4XrIbVsQIwTJWKDiBVRbr8qq4xKp9mAOmX2KYjUBwIxk/" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="1084" data-original-width="1878" height="370" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXpXroFbEzoZaNS6aJUsXD-jqn1PvrLVArV3RfGuWwhyEwEMiAbwj6DVcOx_Bwiwor3R7-c23VXzirkYbkzE6Mj2O68rC4Z7x4XrIbVsQIwTJWKDiBVRbr8qq4xKp9mAOmX2KYjUBwIxk/w640-h370/sweden.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Sweden trends</td></tr></tbody></table></p><h4>New York state, Califronia state and USA. </h4><div><div>Few highlights from USA on the measures observed : </div><div><br /></div><div>- Full lockdowns for parts of time.</div><div>- Events on/off closed down to varings size. </div><div>- Schools on/off closed down.</div><div>- Mask usage and recommendations for reduced travel.</div></div><div><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWtfjfaJDVxJ1ZYc5rAuuyQe_tTlICCDhEbBJX3TlcCiTCMjn_5uofdrS0X1HnNbZfRa87isXKYSeETMkAXBU8Ohp9pFZ7XOUBFg8qIAkku7YOdz6rZJeqR-FH_2QH8P3xKy332vSEcHo/" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="1190" data-original-width="2048" height="372" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWtfjfaJDVxJ1ZYc5rAuuyQe_tTlICCDhEbBJX3TlcCiTCMjn_5uofdrS0X1HnNbZfRa87isXKYSeETMkAXBU8Ohp9pFZ7XOUBFg8qIAkku7YOdz6rZJeqR-FH_2QH8P3xKy332vSEcHo/w640-h372/EkwNqDpXYAEN2cu.jpeg" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">New York trends<br /><br /></td></tr></tbody></table></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidTbeRGKAW8eLUH6bWNAXpmBwCFgPUGOFXLeRE2ogcC0AepK1V87pENbPkkB5sLTVo0d7nvoeLf0vXOeDzUe5Ed3QNhW2btyo2X1KLzBw6Pv9t5be675fUkvwz9WkJhwQnNWXv8BrfH2k/" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="1076" data-original-width="1882" height="366" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidTbeRGKAW8eLUH6bWNAXpmBwCFgPUGOFXLeRE2ogcC0AepK1V87pENbPkkB5sLTVo0d7nvoeLf0vXOeDzUe5Ed3QNhW2btyo2X1KLzBw6Pv9t5be675fUkvwz9WkJhwQnNWXv8BrfH2k/w640-h366/california.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">California <br /></td></tr></tbody></table><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvuIr-eCWJdYb999-jE93yL2CZz6NFXkL6ZUeIGPja8iwhizVw_AiNat6LP2jVFMXDeQYFJTklEx2qeE1USAIRZ0j2M-VfxbpoDVtDExOFofOVjb1mgZPdT_YcEy2KJ8ctvG7pKTw5qmw/" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="1172" data-original-width="2048" height="366" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvuIr-eCWJdYb999-jE93yL2CZz6NFXkL6ZUeIGPja8iwhizVw_AiNat6LP2jVFMXDeQYFJTklEx2qeE1USAIRZ0j2M-VfxbpoDVtDExOFofOVjb1mgZPdT_YcEy2KJ8ctvG7pKTw5qmw/w640-h366/usa-11-oct.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">USA overall<br /></td></tr></tbody></table><br /><br /></div><h4 style="text-align: left;">Berlin and Germany</h4><div><div>Few highlights from Germany on the measures observed : </div><div><br /></div><div>- Full lockdowns for parts of time.</div><div>- Events on/off closed down to varings size. </div><div>- Schools on/off closed down.</div><div>- Mask usage and recommendations for reduced travel.</div></div><div><br />Quite similar to the US from a restriction standpoint. <table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgbj0SJbd4Wrv3rfgEWif7QruCsBwV-AhWMxz9qzFrgaimgRaa0R9vq2bFvzU_e_KUFREGfk8XTs3D915hUqEzfhpv-T-i9kqhlJtxBlgPCkXCWsM3yMEK-2FXu7RTmOds73ZLH4nx1TQ/" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="1090" data-original-width="1878" height="372" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgbj0SJbd4Wrv3rfgEWif7QruCsBwV-AhWMxz9qzFrgaimgRaa0R9vq2bFvzU_e_KUFREGfk8XTs3D915hUqEzfhpv-T-i9kqhlJtxBlgPCkXCWsM3yMEK-2FXu7RTmOds73ZLH4nx1TQ/w640-h372/berlin+11+oct.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Berlin<br /></td></tr></tbody></table></div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEYpkCPsD_1yrDuBq8gl3pZmtCadHbzjtX031auxtLfLvubzcYOLFCC3NxDPqAyUEQtNfmbO8PF1oZ67LPzoyTA5GjVnu7ux3VejF7WMQ2jBFxoirQwXwsbuCq9S-fRH688B2PM_momEE/" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="1092" data-original-width="1884" height="370" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEYpkCPsD_1yrDuBq8gl3pZmtCadHbzjtX031auxtLfLvubzcYOLFCC3NxDPqAyUEQtNfmbO8PF1oZ67LPzoyTA5GjVnu7ux3VejF7WMQ2jBFxoirQwXwsbuCq9S-fRH688B2PM_momEE/w640-h370/germany-11+-+oct.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Germany overall</td></tr></tbody></table><br /><br />My take on the data is that all locations above have similar behavior changes. Lot more peapole go out to national parks, public beaches, marinas, dog parks, plazas, and public gardens. This can be seen by the increase of shopping for sporting eqvipemnt and bikes. Here is just one example of many <a href="https://www.theguardian.com/business/2020/jun/26/bike-boom-uk-sales-up-60-per-cent-in-april-as-covid-19-changes-lifestyles">Bike boom: UK sales up 60% in April as Covid-19 changes lifestyles</a>. </div><div><br /></div><div>Lot more employees work remotely more across the board, more then just tech companies even though there has been a large share of those as well. <a href="https://www.theverge.com/2020/10/9/21508964/microsoft-remote-work-from-home-covid-19-coronavirus">Microsoft</a> being on of the latest companies to make it a permanate change. </div><div><br /></div><div>All of this has led to lot less traveling which is not suprussing. What is supurssing though is that different measures led to similar behaviour. For me leaving as an expat in Sweden it has been fascinating to see amount of trust the peapole have in government institutions and how many of them have respected the guidelines. </div><div><br /></div><div>The Economist had a recent article "<a href="www.economist.com/leaders/2020/10/10/the-real-lessons-from-swedens-approach-to-covid-19?fsrc=scn/tw/te/bl/ed/landofthemaskfreethereallessonsfromswedensapproachtocovid19leaders">The real lessons from Sweden’s approach to covid-19</a>", I personally think its more a <a href="https://en.wikipedia.org/wiki/Lagom">Lagom</a> approach then pragamtisam but ether way the trends seam to be during in the negative directions the last weeks, I sure hope things turn out for the better! </div>Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-18446765523649876902016-02-29T00:01:00.004+01:002020-11-09T17:48:20.804+01:002015 conference talks<p>
The past 2015 has been very eventful year for me on both professional and private plan.
I got married, moved to Sweden, started working for Klarna and did a lot of talks on events around Europe, here are the recordings and summaries of them
</p>
<h2>JPrime 2015: the core libraries you always wanted</h2>
<p>
It was a great community event organized by BGJUG. I also got a chance to meet up with some of the friends there.
One big highlight of the conf for me was beeing able to meet <a href="http://stackoverflow.com/users/203907/bozho">Bozho</a>, one of the top contributors on StackOveflow. We even got a selfie but after an extensive search I am unable to find it.
The team is preparing next year's event and they had few smaller events in the meantime like <a href="https://mihail.stoynov.com/2016/02/20/jug-bg-jprofessionals-2-0/">JProffesionals</a>.
In any case here is my talk on goodies from Guava:
</p>
<iframe width="700" height="400" src="https://www.youtube.com/embed/96R9I1i0AM4" frameborder="0" allowfullscreen></iframe>
<br/>
<h2>Voxxed days Belgrade 2015: Microservice and distributed systems decoupling patterns</h2>
<p>
A first-time event for the <a href="http://heapspace.rs/">Heap Space</a> community and the best Voxxed event I have been( probably best of them all). Great content, awesome speakers and superb organization.
Some photo from the organizers :
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnm4UjIOGUAQuKWPmgUzuhUBmBs1sEwfytIJhtUg8tUt2VtW_tRE60nLSDELH57eiO3TssFnv6gAjcToEWyr8xGqatqVe0fVvvid3rlOs5jEgZqxtT9acm35qFl4Q3HknH9Eit-ZgK3uw/s1600/voxxed-all.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnm4UjIOGUAQuKWPmgUzuhUBmBs1sEwfytIJhtUg8tUt2VtW_tRE60nLSDELH57eiO3TssFnv6gAjcToEWyr8xGqatqVe0fVvvid3rlOs5jEgZqxtT9acm35qFl4Q3HknH9Eit-ZgK3uw/s1600/voxxed-all.jpg" /></a></div>
<iframe width="700" height="400" src="https://www.youtube.com/embed/qW9GCl8kiu0" frameborder="0" allowfullscreen></iframe>
</p>
<br/>
<h2>Devoxx BE 2015 : Updates to the Java API for JSON Processing for Java EE 8 with Alex Soto </h2>
<p>
It is one of the best conference in the Java world and I was delighted to have a talk with <a href="www.lordofthejars.com">Alex</a> on the JSR we have been working on.
It's the latest <a href="https://www.jcp.org/en/jsr/detail?id=374">additions</a> to the JSON processing for Java EE. One mind blowing thing for me was that in parallel with us there was a talk by Andrew Tanenbaum.
And yes it is THE Andrew Tanenbaum. While there were tons of other great stuff during the conference this was my personal highlight.
<iframe width="700" height="400" src="https://www.youtube.com/embed/t87W95Y_qDE" frameborder="0" allowfullscreen></iframe>
</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/on2Gcbx8GXeb8Y" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/maggandalf/updates-to-the-java-api-for-json-processing-for-java-ee-8" title="Updates to the java api for json processing for java ee 8" target="_blank">Updates to the java api for json processing for java ee 8</a> </strong> from <strong><a target="_blank" href="//www.slideshare.net/maggandalf">Alex Soto</a></strong> </div>
<p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">The room is full for <a href="https://twitter.com/alexsotob">@alexsotob</a> and <a href="https://twitter.com/mitemitreski">@mitemitreski</a> talk about JSON processing for Java EE 8 <a href="https://twitter.com/hashtag/Devoxx?src=hash">#Devoxx</a> <a href="https://t.co/3RmKOxMFfw">pic.twitter.com/3RmKOxMFfw</a></p>— Arnaud Héritier (@aheritier) <a href="https://twitter.com/aheritier/status/664745687398146048">November 12, 2015</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGRobmgas6HSYrIA-50YgWL_xh_Ycwz86YJf9UOLYBbrLpPqzbCM7HwFK5CdWnReSw72suOZkbiSgYcxvSqme10hPBbkzxv_4CmZwqcQF246kuG6_KE5jcbigbVSnqJWVtKvbriWYabIQ/s1600/CTxwt8wWIAAf_uB.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGRobmgas6HSYrIA-50YgWL_xh_Ycwz86YJf9UOLYBbrLpPqzbCM7HwFK5CdWnReSw72suOZkbiSgYcxvSqme10hPBbkzxv_4CmZwqcQF246kuG6_KE5jcbigbVSnqJWVtKvbriWYabIQ/s1600/CTxwt8wWIAAf_uB.jpg" /></a></div>
<p>
Same year I also talked on VoxxedDays Istanbul and had a panel on EOUS.
I am happy to have taken part in all of these events and hope to have brought value to the folks who listen them.
Until next time ...
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUJP0sDmuSyuvWn61g1CEMFsyGx4jKdv2_AfA5cJ9io8lujuBd2OBNNEIGMe6n_mGms0VjfI90CXNvlcHzR95L7mSN7qXMDOWIkTW91m7AV0oFLEZzwhNF3gub3ok_Bo0CHPBNeQM9-SQ/s1600/ending+slide.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUJP0sDmuSyuvWn61g1CEMFsyGx4jKdv2_AfA5cJ9io8lujuBd2OBNNEIGMe6n_mGms0VjfI90CXNvlcHzR95L7mSN7qXMDOWIkTW91m7AV0oFLEZzwhNF3gub3ok_Bo0CHPBNeQM9-SQ/s400/ending+slide.jpg" /></a></div>
</p>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-61437932230279266302016-02-26T19:51:00.003+01:002020-11-09T17:48:10.803+01:00JFokus 2016 : Java Awesomeness in the Heart of Scandinavia<blockquote cite="https://www.voxxed.com/blog/2016/02/jfokus-2016-bringing-awesomeness-heart-scandinavia/"> Originally published on Voxxed <a href="https://www.voxxed.com/blog/2016/02/jfokus-2016-bringing-awesomeness-heart-scandinavia/">https://www.voxxed.com/blog/2016/02/jfokus-2016-bringing-awesomeness-heart-scandinavia/</a>
</blockquote>
After watching many sessions online, this year I was able to attend <a href="https://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwin3Pf2kYvLAhVJPBQKHf9_BjgQFggdMAA&url=http%3A%2F%2Fwww.jfokus.se%2F&usg=AFQjCNHcFTHhg7xTZNfYeB5Jtve0OwF9aQ" target="_blank">Jfokus</a> in person for the first time. This was the 10th edition of the event, bringing over 1800 attendees. One other thing to note is that the conference was sold out 2 weeks in advance, which as JFokus main organiser <a href="https://twitter.com/matkar?lang=en" target="_blank">Mattias Karlsson</a> commented, "hasn't happened in several years". This is testament that the Java community is still alive and kicking after all this time.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSKGQOoffAbYL-hYG9MedpKLLLn9itBSRtoon-s0m14YWt_mj4qZhcKA1fkyY8Nj2n7Yuf3D6EZa0KPS6IaYHy8uA8izGucQ8WVfbIu4_Q5_MuD5OPOUMp8o-K0kz2WWW9yCt0qjSjHlE/s1600/jfocus+%25281%2529.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSKGQOoffAbYL-hYG9MedpKLLLn9itBSRtoon-s0m14YWt_mj4qZhcKA1fkyY8Nj2n7Yuf3D6EZa0KPS6IaYHy8uA8izGucQ8WVfbIu4_Q5_MuD5OPOUMp8o-K0kz2WWW9yCt0qjSjHlE/s400/jfocus+%25281%2529.jpg" /></a> <br />
<br />
Amusement park fair party As a prequel to the main conference, there was a JFokus VM Tech Summit chaired by my Klarna colleague <a href="https://twitter.com/lagergren?lang=en">Markus Lagergren</a>. Unfortunately, I didn't got visit this part of the event but <a href="https://twitter.com/speakjava">Simon Ritter</a> has a great write up on the <a href="https://www.azul.com/focusing-10-years-jfokus/">Azul blog</a>. The same day university sessions with 3 hour presentations on topics ranging from Mob Programming to <a href="http://www.jfokus.se/jfokus16/preso/Industrial-Prototyping-with-TinkerForge.pdf" target="_blank">TinkerForge</a> and <a href="http://www.jfokus.se/jfokus16/preso/PracticalRxJava.pdf" target="_blank">RXJava</a>. The conference day started off with a great keynote by <a href="http://www.jfokus.se/jfokus16/preso/Move-Slowly.pdf" target="_blank">Brian Goetz</a> on Java's evolution and future evolution.
<iframe width="660" height="315" src="https://www.youtube.com/embed/TkpcuL1t1lY" frameborder="0" allowfullscreen></iframe> <br/>
There were many great talks throughout the day and you can see the speaker lineup as well as some of the presentation slides on the <a href="http://www.jfokus.se/jfokus/schedule.jsp" target="_blank">schedule</a> page. I would really like to highlight a few which really got me thinking:<br />
<ul>
<li>'Git from the Bits Up' by Tim Berglund followed the creation of a git repository and how the information is internally represented by looking at the <code>.git</code> folder.</li>
<li>'<a href="http://www.jfokus.se/jfokus16/preso/ConcurrentToParallel.pdf" target="_blank">From Concurrent to Parallel' </a>by Brian Goetz took me back to the college days of a parallel vs. serial code</li>
<li>Making Java more dynamic by <a href="https://twitter.com/rafaelcodes?lang=en" target="_blank">Rafael Winterhalter</a> covered the awesome topic of bytecode manipulation and how <a href="http://bytebuddy.net/#/" target="_blank">Byte Buddy</a> can make things more simple.</li>
</ul>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Attending <a href="https://twitter.com/hansolofx">@hansolofx</a> talk at <a href="https://twitter.com/hashtag/jfokus?src=hash">#jfokus</a> <a href="https://twitter.com/hashtag/IoT?src=hash">#IoT</a> - Great talk! <a href="https://t.co/Fvr7fNRRmJ">pic.twitter.com/Fvr7fNRRmJ</a></p>— Yara M H Senger (@yarasenger) <a href="https://twitter.com/yarasenger/status/697372371330715650">February 10, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
Throughout the conference, <a href="https://twitter.com/_nighthacking" target="_blank">Stephen Chin</a> was live streaming and filming his NightHacking sessions. You can find the recordings on his <a href="http://nighthacking.com/category/jfokus-2016/" target="_blank">blog</a> but I would like to recommend the one from Simon Ritter on Struct-Like Performance in Java. The organisation was also excellent - internet at all times and no technical problems. I particularly enjoyed the amusement park-like theme of the party and the Atlassian and Red Hat bars. What followed the conference as a three day speakers (un)conference. Unfortunately this was not open for the general public, but two lucky people were selected to join the speakers in Vemdalen. Having taken part in unconferences before, I do understand the need to keep it small, but I would say that having few more outsiders is always good for the community. Here are few Tweets from behind the scenes:<br />
<blockquote class="twitter-tweet">
<div dir="ltr" lang="en">
Good bye <a href="https://twitter.com/hashtag/Jfokus?src=hash">#Jfokus</a> speaker conf. Thanks for joining. <a href="https://t.co/vntNrtqgmt">pic.twitter.com/vntNrtqgmt</a></div>
— Jfokus (@Jfokus) <a href="https://twitter.com/Jfokus/status/698542068210257920">February 13, 2016</a></blockquote>
<blockquote class="twitter-tweet">
Awesome Speakers Conference 10-13! Thanks for inviting me <a href="https://twitter.com/matkar">@matkar</a> It was a blast! 💟 <a href="https://twitter.com/hashtag/jfokus?src=hash">#jfokus</a> <a href="https://twitter.com/hashtag/gde?src=hash">#gde</a> <a href="https://twitter.com/hashtag/community?src=hash">#community</a> <a href="https://t.co/jTgUAO5uxH">pic.twitter.com/jTgUAO5uxH</a>
— gerardsans (@gerardsans) <a href="https://twitter.com/gerardsans/status/698489651842183168">February 13, 2016</a></blockquote>
<blockquote class="twitter-tweet">
<div dir="ltr" lang="en">
Wow epic <a href="https://twitter.com/hashtag/iot?src=hash">#iot</a> hacking w <a href="https://twitter.com/Jfokus">@jfokus</a> speakers! <a href="https://t.co/MYfqvwBwIT">pic.twitter.com/MYfqvwBwIT</a></div>
— Ray Tsang (@saturnism) <a href="https://twitter.com/saturnism/status/698188725432492032">February 12, 2016</a></blockquote>
Last but not least, here is a message from the JFokus team<br />
<blockquote class="twitter-tweet">
Thank you all for coming to <a href="https://twitter.com/hashtag/Jfokus?src=hash">#Jfokus</a> 2016. <a href="https://twitter.com/hashtag/Helium?src=hash">#Helium</a> message from <a href="https://twitter.com/hashtag/mrJfokus?src=hash">#mrJfokus</a> <a href="https://twitter.com/matkar">@matkar</a> . <a href="https://t.co/wHY8z0jw1q">pic.twitter.com/wHY8z0jw1q</a>
— Helena Hjertén (@javaHelena) <a href="https://twitter.com/javaHelena/status/697432419696275456">February 10, 2016</a></blockquote>
And a few other images of the event up on the <a href="https://www.flickr.com/groups/jfokus2016/pool/">Flickr</a> page, Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-25267828490205608552015-02-04T00:51:00.000+01:002020-11-09T22:20:52.963+01:00HttpClient 4.x Timeout <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1j8H-12E5pOxl2qTcoHmr-XOIbXi5UItYpS2sLG6ak7hzkvbgVUWpGTu10ACRqRyajUQ8XgOuGg5OhUCsZyhXeO_qAMl6lrvfbJd7m-IsNLT1AEdtFwGCxWvaMuVuaBFXzESgDmnSwOU/s1600/timeout.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1j8H-12E5pOxl2qTcoHmr-XOIbXi5UItYpS2sLG6ak7hzkvbgVUWpGTu10ACRqRyajUQ8XgOuGg5OhUCsZyhXeO_qAMl6lrvfbJd7m-IsNLT1AEdtFwGCxWvaMuVuaBFXzESgDmnSwOU/s1600/timeout.jpg" height="480" width="640" /></a><br />
<br />
HttpClient is one of the most versatile Java libraries. Unfortunately, it comes with a lot of configuration options that may be way too cryptic or difficult. While the API for 4.x series has been significantly improved there are still some sharp edges.<br />
<br />
<h2>
The deprecated or 3.x way of setting the timeout.</h2>
This is done using params. Note that this is still 4.x code but a deprecated one.<br />
<pre><code>
DefaultHttpClient httpClient = ...;
HttpParams httpParams = httpClient.getParams();
httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000L);
httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, 1000L);
httpParams.setParameter(ClientPNames.CONN_MANAGER_TIMEOUT, 1000L);
</code>
</pre>
Now the part httpClient.getParams() is deprecated since obviously this is a nasty API. You need to keep track of parameters with Enums/constants and their type as well.<br />
<br />
<h2>
The right 4.x way aka the builder way</h2>
<br />
HttpClient 4 is full of builder for everything. While I often love the Builder patterns in some cases the testing part is really difficult but I guess it is always a tradeoff. This would be the "right way".<br />
<pre><code>
public RequestConfig requestConfigWithTimeout(int timeoutInMilliseconds) {
return RequestConfig.copy(RequestConfig.DEFAULT)
.setSocketTimeout(timeoutInMilliseconds)
.setConnectTimeout(timeoutInMilliseconds)
.setConnectionRequestTimeout(timeoutInMilliseconds)
.build();
}
</code>
</pre>
<h2>
</h2>
<h2>
The meaning of the parameters</h2>
Notice that we are actually setting 3 different timeouts.<br />
<ul>
<li><b>Socket Timeout</b> - this is the time of inactivity to wait for packets to arrive</li>
<li><b>Connection Timeout</b> - the time to establish a connection with the remote host</li>
<li><b>Connection Manager Timeout</b> - the time to fetch a connection from the connection pool</li>
</ul>
The third one costed me dearly, it wasn't until the client was under a high load that issues started happening. The connection pool I was using had 10 connections per route limitation set and the scenario was quite common. As you can see these settings do not provide a mechanism for making an N millisecond hard timeout.<br />
<br />
If we were to setup the timeout to 10 seconds on each of this we could end up with a request that lasts 9(sec to get a connection) + 9( sec to open connection ) + 9( sec of inactivity ) = 27 sec.<br />
<br />
<h2>
More info</h2>
A bug when setting the <a href="https://issues.apache.org/jira/browse/HTTPCLIENT-1418">ConnectionRequestTimeout</a><br />
The RequestConfig <a href="http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/config/RequestConfig.html">Javadoc</a><br />
Apache HttpClient <a href="https://hc.apache.org/httpcomponents-client-ga/examples.html">examples</a>Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-82606493494488973132015-01-31T22:49:00.002+01:002020-11-09T17:48:33.974+01:00JavaDay 2014 a leap forward<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPvj5F7b1i6kt42GgGTWZqZkOdXH_mOuqZ9ciUGfoET_UbGUu2TcTH-yHmvOwdXkc14kI2onuzHClAVne3G7S8VDVICDbUCbgSlsTzBrjA3wQdMxBTisR49kcMtAVV5Ieu8lVgXXL5C60/s1600/javaday.jpeg" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPvj5F7b1i6kt42GgGTWZqZkOdXH_mOuqZ9ciUGfoET_UbGUu2TcTH-yHmvOwdXkc14kI2onuzHClAVne3G7S8VDVICDbUCbgSlsTzBrjA3wQdMxBTisR49kcMtAVV5Ieu8lVgXXL5C60/s1600/javaday.jpeg" height="425" width="640" /></a></div>
<br />
Java Day is an event that<a href="http://www.jug.mk/"> jug.mk</a> organizes for the past 5 years. From the small group of enthusiastic presenters in EU-info center in Skopje to a full 7h filled with lectures at a cinema hall JavaDay has grown to be one of the leading technical events in the area.<br />
<br />
<h3>
What has changed over the years and what the future holds</h3>
We started out as a small event with only local speakers in 2009 happening each year since then. In 2013, we had 1 person outside of Macedonia. The need for diversity was becoming more apparent. 2014 was the year we went fully international with 6 speakers coming from Switzerland, Serbia, and Bulgaria. We had participants in the audience from all the neighboring countries.<br />
The Bulgarian JUG presence was a great addition and an awesome connection between our JUGS.<br />
<br />
<h3>
The keynote </h3>
<div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTCkXhi5DLqOm64MhyphenhyphenjJ4RdBi_q6fa2C2Bk0xN_FUO6VOnZL2p3TS0gQdrPABnF-ZmTZ-djODrVPgNaZgG7tLERRvBK-2tzLUh_uae7SjQkxQ78TGqJGpq8H4glzGtx5W_FZC99cmR5XQ/s1600/JavaDay2014+(14%2Bof%2B19).jpg" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTCkXhi5DLqOm64MhyphenhyphenjJ4RdBi_q6fa2C2Bk0xN_FUO6VOnZL2p3TS0gQdrPABnF-ZmTZ-djODrVPgNaZgG7tLERRvBK-2tzLUh_uae7SjQkxQ78TGqJGpq8H4glzGtx5W_FZC99cmR5XQ/s1600/JavaDay2014+(14%2Bof%2B19).jpg" height="425" width="640" /></a></div>
<a href="https://twitter.com/corsin"><br /></a> <a href="https://twitter.com/corsin">Corsin Decurtins,</a> CTO of Netcetera gave an awesome talk on "how to become a great developer".<br />
To quote the abstract:<br />
<blockquote class="tr_bq">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoKwA33E9XX6phuhwle3Nzk-q5RR39Cf0FCSqKaiTziajWTLo2WkVgF7e-zS8csr9xJUjhtXyXlDF2ZP7K9uoKYlezRxA_uv0cQF0maLwJZSx5eKgDDauHIXH06laGaNaZtXmZ-1N3Oz8/s1600/43c4528e.corsin.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoKwA33E9XX6phuhwle3Nzk-q5RR39Cf0FCSqKaiTziajWTLo2WkVgF7e-zS8csr9xJUjhtXyXlDF2ZP7K9uoKYlezRxA_uv0cQF0maLwJZSx5eKgDDauHIXH06laGaNaZtXmZ-1N3Oz8/s1600/43c4528e.corsin.jpg" /></a><span style="background-color: white; color: #333333; font-size: 14px; line-height: 20px;">At the core, the job of a software developer is and has always been the same: writing good, elegant, sustainable and bug-free software that exceeds the expectations of your clients. But the context in which we do our job is changing and with it the skills required to be a great software developer. In this talk, I want to go through a couple of things that I think make the difference between a developer and a great developer. This includes some technical skills and practices, but also non-technical things that you might not consider relevant for a developer at first.</span></blockquote>
The talk was extremely well perceived by the audience. This is very visible by the survey where he got the best reviews also by the fact the we were approached multiple times by persons telling us we need more of this.<br />
<h3>
Why this type of events are important to the community </h3>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjunLHGwjMNsNGmHJzFZw2WCoaLeg_dgFeuKrX0dIQ86d5v45KxezUetEsSBFOzjzhMuGUwB_ej902hQy0s5CcIb6xRJfGBifXOTgEdskll3FLp3BrqbgmCK9tMWUo_YpMF8EhZFP5IkRk/s1600/P1011722.JPG" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjunLHGwjMNsNGmHJzFZw2WCoaLeg_dgFeuKrX0dIQ86d5v45KxezUetEsSBFOzjzhMuGUwB_ej902hQy0s5CcIb6xRJfGBifXOTgEdskll3FLp3BrqbgmCK9tMWUo_YpMF8EhZFP5IkRk/s1600/P1011722.JPG" height="480" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
Conferences help you get in touch with other like-minded persons. They keep you up to date with modern technologies and interesting concepts. Also it is great for the companies where it enables them to reach narrowly selected audience, they get to promote himself and be recognizable.</div>
<div>
<br /></div>
<h3>
Female participation @ JavaDay</h3>
<div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgseeohl4nvpLGhmBHCqOTZq58t4QXXz0S0ycM6P5tHGKNGZhdylaz6vbdsCMwvrJG8l-GoA9kgglM9eGdhpoCcL914BnxR79PYbwIYWH1xVPshSAEJsKSaBM-OCx16O5QQpqXdb3_2C6c/s1600/raluca.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgseeohl4nvpLGhmBHCqOTZq58t4QXXz0S0ycM6P5tHGKNGZhdylaz6vbdsCMwvrJG8l-GoA9kgglM9eGdhpoCcL914BnxR79PYbwIYWH1xVPshSAEJsKSaBM-OCx16O5QQpqXdb3_2C6c/s1600/raluca.jpg" height="200" width="182" /></a></div>
<div>
This year we also had our first female speaker Raluca Breaur one of the organizers or the Agile meetups and Java User Group in Iasi, Romania. She had an awesome talk "Caching – oldie but goldie" with great analogies for caching systems.<br />
It is unfortunate that after so many JavaDay this was our first female speaker especially since the from the side of the attendees we had more than 30%. </div>
<div>
Few weeks later a nice initiative was started by forming a local chapter of JDutchess. Few of them were also involved in the organization and we extremely grateful.<br />
I am just hoping that next years event will have lot more of this group.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF2-R8tjHza0gZkmERglUTmttFSgFc2leP3qxGCqZxxPgD3AJ5e3UuaQJnSI3QwAJ1SkqgaymUJVIOI-3-21B6ITjcZ55jz1if7ko02P_lIizpIWaiM-C6qZ4DktMIeVJj7rTKSWu5Cc8/s1600/P1011731.JPG" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF2-R8tjHza0gZkmERglUTmttFSgFc2leP3qxGCqZxxPgD3AJ5e3UuaQJnSI3QwAJ1SkqgaymUJVIOI-3-21B6ITjcZ55jz1if7ko02P_lIizpIWaiM-C6qZ4DktMIeVJj7rTKSWu5Cc8/s1600/P1011731.JPG" height="480" width="640" /></a><br />
<br /></div>
<div>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
What's next </h3>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9XWbY8U52UuC4FvNk6t1a6_769pobsuajheXlUa2OpBFD0-R4H81y724iwy4whriodbwbdT9X_l8lOu6B-caCLLikr8G-d5oHN2cNKyndP69-9DWTUZERrMbWTANWnR5eFusvcJ0neAE/s1600/JavaDay2014+(10%2Bof%2B19).jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9XWbY8U52UuC4FvNk6t1a6_769pobsuajheXlUa2OpBFD0-R4H81y724iwy4whriodbwbdT9X_l8lOu6B-caCLLikr8G-d5oHN2cNKyndP69-9DWTUZERrMbWTANWnR5eFusvcJ0neAE/s1600/JavaDay2014+(10%2Bof%2B19).jpg" height="424" width="640" /></a></div>
<div>
<br /></div>
Hopefully sometime in the near future we are gonna get the video recordings processed and uploaded to Parleys.<br />
We continue next year and try to make the event better. Going bigger is also an option but we are not sure if that is the right direction. We definitely wanna raise the organization level and the quality of the event.<br />
Special thanks to the 7 sponsors that supported up and without them the event could not be free.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWYfJWpEGIkF8oOPieGjpEqbtiKhlkGP8BUglCpPh0TORlGpGRRloBGDHVWvtnQt3lrE0Z9x9mtQnF8ZPdgTs6wQl86ZtuozNyKpzX8JcP9ABh0i8avyMjD7-zvFbvjQi7jn3_tcgMVK8/s1600/P1011751.JPG" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWYfJWpEGIkF8oOPieGjpEqbtiKhlkGP8BUglCpPh0TORlGpGRRloBGDHVWvtnQt3lrE0Z9x9mtQnF8ZPdgTs6wQl86ZtuozNyKpzX8JcP9ABh0i8avyMjD7-zvFbvjQi7jn3_tcgMVK8/s1600/P1011751.JPG" height="480" width="640" /></a><br />
<br />
We had a little competition about choosing the next name for JavaDay so next year we might be called Javalicious. </div>
<div>
<table align="center" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYdEVw_XvnS6OcBquKVeKLotSTO5rRHh7nH7YNzpn_fO7Kk-5au0ogX4fasPiMMLp9LpxUlpNrlCC4a8qhUHXapx3RrNExq3FbtfVCW8N2ei0Dv0zpWU1BeIjlv7gQaWqjZcKejRAwXJs/s1600/P1011775_v1.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYdEVw_XvnS6OcBquKVeKLotSTO5rRHh7nH7YNzpn_fO7Kk-5au0ogX4fasPiMMLp9LpxUlpNrlCC4a8qhUHXapx3RrNExq3FbtfVCW8N2ei0Dv0zpWU1BeIjlv7gQaWqjZcKejRAwXJs/s1600/P1011775_v1.JPG" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The organizing team</td></tr>
</tbody></table>
<br />
<h3>
The survey</h3>
</div>
<div>
Notice the Gaussian distribution for the speaker reviews :) </div>
<br />
<div style="border-top: 1px solid #acacac; font-family: Arial; font-size: 10px; padding-top: 3px; text-align: center; width: 100%;">
<a href="https://infogr.am/java_day_2014-361" style="color: #acacac; text-decoration: none;" target="_blank">Java Day 2014</a> | <a href="https://infogr.am/" style="color: #acacac; text-decoration: none;" target="_blank">Create infographics</a></div>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-12303039460893117492015-01-21T16:40:00.000+01:002020-11-09T22:21:04.663+01:00A New Try-with-resources Improvement in JDK 9The <a href="http://openjdk.java.net/jeps/213" target="_blank">JEP 213 - Milling Project Coin</a> is a follow up to the <a href="http://openjdk.java.net/projects/coin/" target="_blank">Project Coin</a> additions to Java 7. Note, as the JEP states, this <em>isn't</em> a Project Coin 2.0. It's more of an attempt at smoothing the "rough edges" that came along with these additions.
Just as a reminder - with the original Project Coin, among other things, we got:
<br />
<ul>
<li>Strings in switch</li>
<li>Binary integral literals and underscores in numeric literals</li>
<li>Multi-catch and more precise rethrow</li>
<li>Improved type inference for generic instance creation (diamond)</li>
<li>Try-with-resources statement</li>
<li>Simplified varargs method invocation</li>
</ul>
Try with resources has been a great simplification, especially when working with I/O code. The addition in JDK 9 is an improvement of the standard <a href="http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html" target="_blank">try-with-resources</a> way of writing code.
Previously in Java 7 and 8 we had;
<br />
<pre><code>
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
// Original try-with-resources statement from JDK 7 or 8
try (BufferedReader r1 = reader) {
// use buffered reader
} catch (IOException e) {
// ignoring exceptions because that is how I roll
}
</code>
</pre>
which works just fine, but we still needed to declare a special variable in the try-with section. The cleaner and simpler way in JDK 9 is now;
<br />
<pre><code>
// The JDK 9 way
try (reader) {
// use the reader
}catch (IOException e){
// ignoring exceptions because that is how I roll
}
</code>
</pre>
This is more "natural" way of writing even though it most use cases we don't need the resource outside the scope of the try block. <span style="line-height: 1.5;">The restriction is that the reader variable should be effectively final or just final.</span>
You can play around with the new way already in the latest <a href="https://jdk9.java.net/download/" target="_blank">JDK 9</a> snapshot.
More info available in <a href="https://blogs.oracle.com/darcy/entry/concise_twr_jdk9" target="_blank">Joe Darcy's </a>Oracle Weblog post and the related JDK <a href="https://bugs.openjdk.java.net/browse/JDK-8068948" target="_blank">bug</a> report.
<br /><br /> Originally published on <a href="https://www.voxxed.com/blog/2015/01/new-try-resources-improvement-jdk-9/">https://www.voxxed.com/blog/2015/01/new-try-resources-improvement-jdk-9/</a>Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-11525803445993789512014-12-18T22:56:00.000+01:002020-11-09T22:21:31.959+01:00Thread Local Storage in Java<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<i>This post is part of the <a href="http://javaadvent.com/" target="_blank"><span style="color: green;">Java</span> <span style="color: red;">Advent</span> <span style="color: green;">Calendar</span></a> and is licensed under the <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">Creative Commons 3.0 Attribution</a> license. If you like it, please spread the word by sharing, Tweeting, FB, G+, etc! </i><br />
<i>It was also republished under <a href="https://www.voxxed.com/blog/2014/12/thread-local-storage-in-java/">https://www.voxxed.com/blog/2014/12/thread-local-storage-in-java/</a></i><br />
<br />
<br />
One of the rarely known features in Java among developers is Thread-local storage. The idea is simple, and the need for it comes in scenarios where we need data that is, <em>well</em>, local for the thread. For example, if we have two threads that refer to the same global variable but we want them to have separate values independently initialized of each other.<br />
<div>
Most major programming languages have implementations of the concept. For example, C++11 has the <a href="http://en.cppreference.com/w/cpp/keyword/thread_local" target="_blank">thread local</a> keyword, and Ruby has chosen an API <a href="http://api.rubyonrails.org/classes/Thread.html#method-i-thread_variable_set" target="_blank">approach</a>.<br />
<div>
Java has also an implementation of the concept with <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.html" target="_blank"> java.lang.ThreadLocal<T></a> and with subclass <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/InheritableThreadLocal.html" target="_blank">java.lang.InheritableThreadLocal<T></a> since version 1.2, so nothing new and shiny here.</div>
<div>
</div>
<div>
Let's say that for some reason we need to have a Long specific for our thread. Using Thread local that would simply be:</div>
<pre class="prettyprint"><code>
public class ThreadLocalExample {
public static class SomethingToRun implements Runnable {
private ThreadLocal threadLocal = new ThreadLocal();
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + threadLocal.get());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
threadLocal.set(System.nanoTime());
System.out.println(Thread.currentThread().getName() + " " + threadLocal.get());
}
}
public static void main(String[] args) {
SomethingToRun sharedRunnableInstance = new SomethingToRun();
Thread thread1 = new Thread(sharedRunnableInstance);
Thread thread2 = new Thread(sharedRunnableInstance);
thread1.start();
thread2.start();
}
}
</code>
</pre>
<div>
One possible sample run of the following code will result in:<br />
<pre class="prettyprint"><code>
Thread-0 null
Thread-0 132466384576241
Thread-1 null
Thread-1 132466394296347
</code>
</pre>
In the beginning the value is set to null to both threads, obviously each of them works with separate values since after setting the value to <i>System.nanoTime()</i> on <i>Thread-0</i> it will not have any effect on the value of <i>Thread-1 </i>exactly as we wanted, a thread scoped long variable. One nice side effect is a case where the thread calls multiple methods from various classes. They will all be able to use the same thread scoped variable without major API changes. Since the value is not explicitly passed through one might argue it difficult to test and bad for design, but that is a separate topic altogether.<br />
<br />
<h3>
In what areas are popular frameworks using Thread Locals?</h3>
Spring, being one of the most popular frameworks in Java, uses ThreadLocals internally for many parts - easily demonstrated by a simple GitHub <a href="https://github.com/spring-projects/spring-framework/search?p=2&q=threadLocal&utf8=%E2%9C%93" target="_blank">search</a>. Most of the usages are related to the current user's actions or information. This is actually one of the main uses for ThreadLocals in JavaEE world, storing information for the current request like in RequestContextHolder:<br />
<pre class="prettyprint"><code><span class="kwd">private</span> <span class="kwd">static</span> <span class="kwd">final</span> <span class="typ">ThreadLocal</span><span class="pun"><</span><span class="typ">RequestAttributes</span><span class="pun">></span><span class="pln"> requestAttributesHolder </span><span class="pun">=</span>
<span class="kwd">new</span> <span class="typ">NamedThreadLocal</span><span class="pun"><</span><span class="typ">RequestAttributes</span><span class="pun">>(</span><span class="str">"Request attributes"</span><span class="pun">);</span>
</code></pre>
</div>
<div>
Or the current JDBC connection user credentials in <a href="https://github.com/spring-projects/spring-framework/blob/dd2bf28a4f2c20cc6510266f245c619755e851ba/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.java" target="_blank">UserCredentialsDataSourceAdapter</a>. If we get back on RequestContextHolder, we can use this class to access all of the current request information from anywhere in our code. A common use case for this is <a href="https://github.com/spring-projects/spring-framework/blob/dd2bf28a4f2c20cc6510266f245c619755e851ba/spring-context/src/main/java/org/springframework/context/i18n/LocaleContextHolder.java" target="_blank">LocaleContextHolder</a>, which helps us store the current user's locale. Mockito uses it to store the current "global" <a href="https://github.com/mockito/mockito/blob/18dc62d72821fdc54f53ba4a5ca98412ac1f4441/src/org/mockito/internal/configuration/GlobalConfiguration.java" target="_blank">configuration</a> and if we take a look at any framework out there is a high chance we'll find it as well.<br />
<br /></div>
<div>
<h3>
Thread Locals and Memory Leaks</h3>
Now that we've learned about this awesome little feature, let's use it all over the place! Well, we <em>can</em> do that, but if you try a few Google searches, you'll find that most posts out there claim that ThreadLocal is evil. That's not <em>exactly</em> true. It's a nice utility, but in some contexts, you could easily accidentally create a memory leak.<br />
<blockquote class="tr_bq">
“Can you cause unintended object retention with thread locals? Sure you can. But you can do this with arrays too. That doesn’t mean that thread locals (or arrays) are bad things. Merely that you have to use them with some care. The use of thread pools demands extreme care. Sloppy use of thread pools in combination with sloppy use of thread locals can cause unintended object retention, as has been noted in many places. But placing the blame on thread locals is unwarranted.” - Joshua Bloch</blockquote>
</div>
<div>
It is very easy to create a memory leak in your server code using <i>ThreadLocal</i> if it runs on an application server. <i>ThreadLocal</i> context is associated to the thread where it runs and will be garbaged once the thread is dead. Modern app servers use pool of threads instead of creating new ones on each request, meaning you can end up holding large objects indefinitely in your application. Since the thread pool is from the app server, our memory leak could remain even after we unload our application. The fix for this is simple - free up resources you do not need. One other <i>ThreadLocal</i> misuse is API design. Often I have seen use of <i>RequestContextHolder</i>(that holds <i>ThreadLocal</i>) all over the place, like the DAO layer, for example. Later on, if one were to call the same DAO methods outside a request, for instance, and scheduler, he would get a very bad surprise. Even though, the variables in ThreadLocal are local to the thread they are very much global in your code. So, if you want to avoid maintenance developers hunting you down and taking their revenge, make sure you really need this thread scope before you use it.<br />
<br />
<h3>
More info on the topic</h3>
<a href="http://en.wikipedia.org/wiki/Thread-local_storage" target="_blank">http://en.wikipedia.org/wiki/Thread-local_storage</a><br />
<a href="http://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/" target="_blank">http://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/</a><br />
<a href="https://plumbr.eu/blog/how-to-shoot-yourself-in-foot-with-threadlocals" target="_blank">https://plumbr.eu/blog/how-to-shoot-yourself-in-foot-with-threadlocals</a><br />
<a href="http://stackoverflow.com/questions/817856/when-and-how-should-i-use-a-threadlocal-variable" target="_blank">http://stackoverflow.com/questions/817856/when-and-how-should-i-use-a-threadlocal-variable</a><br />
<a href="https://plumbr.eu/blog/when-and-how-to-use-a-threadlocal" target="_blank">https://plumbr.eu/blog/when-and-how-to-use-a-threadlocal</a><br />
<a href="https://weblogs.java.net/blog/jjviana/archive/2010/06/09/dealing-glassfish-301-memory-leak-or-threadlocal-thread-pool-bad-ide" target="_blank">https://weblogs.java.net/blog/jjviana/archive/2010/06/09/dealing-glassfish-301-memory-leak-or-threadlocal-thread-pool-bad-ide</a><br />
<a href="https://software.intel.com/en-us/articles/use-thread-local-storage-to-reduce-synchronization" target="_blank">https://software.intel.com/en-us/articles/use-thread-local-storage-to-reduce-synchronization</a><br />
<br />
<br />
<br /></div>
</div>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-42307946046514177842014-12-18T22:48:00.001+01:002020-11-09T22:21:38.985+01:00How to Not Hate JavaScript: Tips from the Frontline<br />
<i>This article was originally published on voxxed under, <a href="https://www.voxxed.com/blog/2014/11/how-to-not-hate-java-script-tips-from-the-frontline/">https://www.voxxed.com/blog/2014/11/how-to-not-hate-java-script-tips-from-the-frontline/</a></i><br />
<br />
<br />
In my work assisting teams with JavaScript related problems, I’ve noticed some common issues. If you're experiencing frustrations with the language too, this article might be of some assistance. Disclaimer: a few of my tips might be obvious to some of you, but hopefully you’ll find at least some useful nuggets of information here! These pointers are especially useful when dealing with enterprise applications and CMS solutions. This is where we have our code, the CMS code, the code from that team nobody wants to mention...and, of course, all of them are loaded asynchronously.<br />
<h3>
The Debugger Statement</h3>
<br />
This is one of the most underused features when dealing with JavaScript, especially since it’s supported by the majority of browsers. The debugger statement was part of the first edition of ECMA Script so it's been here for quite some time.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJDZosvhp6aN242dsSgaAgJPxQZRVPJ9hSmrclDKd_pDKUzKLley3gIyj9dt49pKv0b5QcRc0Sf8hzj6w5qZSMV_I2x04lYme9BLQmC5Nj-hlZsD1RTdcHW4rTU8HHnDZ_ZJM7M0w7ZJk/s1600/Screen-Shot-2014-11-26-at-17.08.56.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJDZosvhp6aN242dsSgaAgJPxQZRVPJ9hSmrclDKd_pDKUzKLley3gIyj9dt49pKv0b5QcRc0Sf8hzj6w5qZSMV_I2x04lYme9BLQmC5Nj-hlZsD1RTdcHW4rTU8HHnDZ_ZJM7M0w7ZJk/s1600/Screen-Shot-2014-11-26-at-17.08.56.png" height="187" width="640" /></a></div>
<br />
Fundamentally it’s a simple way of adding a breakpoint. If we have code where we loop over an element list and then process the elements...<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUAm9kz3FIOl3d98Lz_x_FkBAvT0mVkcRRDXathIAdUpe7JNxXRtRaChhbSAa9_EKAAvy-nUMAG0EfzWPL0dqyey2xuq-fa3VOK2t524MYHayizUWCqJB5mwJtf765NrryFTUfs8tQcKM/s1600/Screen-Shot-2014-11-26-at-17.10.59.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUAm9kz3FIOl3d98Lz_x_FkBAvT0mVkcRRDXathIAdUpe7JNxXRtRaChhbSAa9_EKAAvy-nUMAG0EfzWPL0dqyey2xuq-fa3VOK2t524MYHayizUWCqJB5mwJtf765NrryFTUfs8tQcKM/s1600/Screen-Shot-2014-11-26-at-17.10.59.png" height="178" width="640" /></a></div>
<br />
...we can add the debugger statement inside the loop so that we have a breakpoint on each iteration:<br />
<br />
<br />
<br />
The triggering of the breakpoint happens when the execution of the code is done in the place where we have added it. In cases where there is no debugger handler - for example in most browsers without dev tools - this statement has no effect.<br />
<br />
On the dev tools side, it will appear as if we have manually placed the breakpoint.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQkbFD1LS6D1C8gG3jn8n4pn-sKXrU8Kqe3-8QMjRT1kDX7zOwhf9FsjD6OZplYK1IugWi8LyXYz67xmu50bVHufG4EsQ6rk59dquGI-q0MoGRN-ZnUwVDLq9CEeudLszbxP3HTtmijO0/s1600/Screen-Shot-2014-11-26-at-17.11.37.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQkbFD1LS6D1C8gG3jn8n4pn-sKXrU8Kqe3-8QMjRT1kDX7zOwhf9FsjD6OZplYK1IugWi8LyXYz67xmu50bVHufG4EsQ6rk59dquGI-q0MoGRN-ZnUwVDLq9CEeudLszbxP3HTtmijO0/s1600/Screen-Shot-2014-11-26-at-17.11.37.png" height="148" width="640" /></a></div>
<br />
<br />
<br />
Of course, this is not for code you want to leave in production, but it is an extremely useful feature during the development period. It has been a life changing feature for me, especially when dealing with the vendor based JavaScript and a whole lot of callbacks.<br />
<div>
<br />
<h3>
Use the Console Luke!</h3>
<br />
Most of the developers use the console.log in for debugging purposes, but did you know about <a href="https://developer.mozilla.org/en-US/docs/Web/API/Console.warn">console.warn</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/Console.error">console.error</a>, and <a href="https://developer.mozilla.org/en-US/docs/Web/API/Console.info">console.info? </a>:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDcUjeIO3I2hSFbhnQrzEXbjeHMoMMm3y0NzHWBfrJJKAa-Q9q887P_qFtqJzaD76lVaL6zKRVzxNRYgq0kXVW-NA473n-CvOl_QT6Q-HLOyhcgBgKg5l7_BGh5p5evjHzPleW3d5Ljgc/s1600/Screen-Shot-2014-11-26-at-17.13.23.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDcUjeIO3I2hSFbhnQrzEXbjeHMoMMm3y0NzHWBfrJJKAa-Q9q887P_qFtqJzaD76lVaL6zKRVzxNRYgq0kXVW-NA473n-CvOl_QT6Q-HLOyhcgBgKg5l7_BGh5p5evjHzPleW3d5Ljgc/s1600/Screen-Shot-2014-11-26-at-17.13.23.png" height="238" width="640" /></a></div>
<br />
<br />
<br />
<br />
All of these support C style <a href="https://developer.chrome.com/devtools/docs/console-api#consolelogobject-object">formatted</a> output like:<br />
<br />
console.log("Hello %s", "Brian");<br />
<br />
There are also plenty of JS <a href="https://www.google.com/search?q=javasciprt+logging+framewors&oq=javasciprt+logging+framewors&aqs=chrome..69i57j0.5145j0j7&client=ubuntu-browser&sourceid=chrome&es_sm=93&ie=UTF-8#q=javascript+logging+frameworks&spell=1">logging</a> frameworks. Proper logging is essential in most programming languages, and JavaScript is no exception to this. Note that not all logging functions are standardized, and you might need to provide fallback for certain browsers. For reference, there is a more extensive article regarding logging in the real world <a href="http://dailyjs.com/2012/02/02/console/">here</a>.<br />
<h3>
Overview of JS objects using Console.table()</h3>
<br />
Often we load data from various services and want have a nice view of it on our console - especially when the data is represented as a list of objects. For example, if we were to load a list of beers from <a href="http://openbeerdatabase.com/">openbeerdatabase.com</a> (yes this database exists, and it is awesome). Using the HTTP GET beers, <a href="http://openbeerdatabase.com/documentation/beers-get">http://openbeerdatabase.com/documentation/beers-get</a> call we receive a list of objects. After receiving the list, we just print it out using console.log:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqRgQxZVwaUvTw0WGV1whC4k7J-NEc_bdfbz9S8ryVK-sTyyNYAjRLlMmpj-GJzMJAYfMBgHL0kW3LT12-FfRas2Q3LLGW5N-3WOQa4NTJNVaiuMaYuhVQwFmDDgC8r0viNdq0w_Ta2ws/s1600/Screen-Shot-2014-11-26-at-17.14.35.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqRgQxZVwaUvTw0WGV1whC4k7J-NEc_bdfbz9S8ryVK-sTyyNYAjRLlMmpj-GJzMJAYfMBgHL0kW3LT12-FfRas2Q3LLGW5N-3WOQa4NTJNVaiuMaYuhVQwFmDDgC8r0viNdq0w_Ta2ws/s1600/Screen-Shot-2014-11-26-at-17.14.35.png" height="246" width="640" /></a></div>
<br />
<br />
The resulting list is difficult to navigate in the console. It’s tricky to get a clear picture of what the data represents. Even if we were to loop through the data, it would still be tedious. Same goes for any large JavaScript object or a list.<br />
<br />
If we were to replace the console.log with console.table and make the call again we'd get this:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9QemIO1yO4Kk3QR5Lr_CPgORu4BRRD3uHwHLLtQgrJhKystHi6YqmhPwesFFFH5WRS8hWuysWhHkaeRZCKls1QU2WIfMSdldhm3L4edvuaWlvtMSXFtjrGVOG9QaBLKhNid9b2f4pWrM/s1600/Screen-Shot-2014-11-26-at-17.15.31.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9QemIO1yO4Kk3QR5Lr_CPgORu4BRRD3uHwHLLtQgrJhKystHi6YqmhPwesFFFH5WRS8hWuysWhHkaeRZCKls1QU2WIfMSdldhm3L4edvuaWlvtMSXFtjrGVOG9QaBLKhNid9b2f4pWrM/s1600/Screen-Shot-2014-11-26-at-17.15.31.png" height="258" width="640" /></a></div>
<br />
<br />
Obviously, the data is shown in a table and it is now sortable using the attributes of the objects. This makes the navigation easier. For example, this is a simple way to visually compare two arrays:<br />
<br />
console.table([[1,2,3], [2,3,4]]);<br />
<br />
would result in more clear version, especially if we had more sub-arrays:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgej0_pS39PD3S5L1ja6gfJFmynUtOIhaLoAO04xEkhyphenhyphenARBU24HP8nD_naaD2BQVJPMZgzhDtfxE5-i8e4yNESjye97S2fI2QrzVORV7MXXG4egcjmzLrGP2BLa2_Ro3Wsixnwxjkyq_TI/s1600/Screen-Shot-2014-11-26-at-17.16.40.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgej0_pS39PD3S5L1ja6gfJFmynUtOIhaLoAO04xEkhyphenhyphenARBU24HP8nD_naaD2BQVJPMZgzhDtfxE5-i8e4yNESjye97S2fI2QrzVORV7MXXG4egcjmzLrGP2BLa2_Ro3Wsixnwxjkyq_TI/s1600/Screen-Shot-2014-11-26-at-17.16.40.png" height="99" width="640" /></a></div>
<br />
<br />
<h3>
Getting the Call Trace</h3>
<br />
Sometimes we want to know the call trace, aka "Who called my function". This is often visible when we get a failure - but even on success, we could get the call trace using console.trace :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR6pOHOz2lYp09zkqJQeF_E4LB3NV4UpYLATVxohoxxA4QKYWEdkkyWLMhyphenhyphenzdoYDXOJEJBVVWTE_u1K7fy6O_fLLw9t2LTsiAD8WktMvKXawQW2ED107Qq8KgOfo6iOBxyu2gU9VAy2ew/s1600/Screen-Shot-2014-11-26-at-17.17.27.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR6pOHOz2lYp09zkqJQeF_E4LB3NV4UpYLATVxohoxxA4QKYWEdkkyWLMhyphenhyphenzdoYDXOJEJBVVWTE_u1K7fy6O_fLLw9t2LTsiAD8WktMvKXawQW2ED107Qq8KgOfo6iOBxyu2gU9VAy2ew/s1600/Screen-Shot-2014-11-26-at-17.17.27.png" height="489" width="640" /></a></div>
<br />
Note that <a href="https://developer.mozilla.org/en-US/docs/Web/API/Console.trace">console.trace</a> is a non-standard functionality and is not something you should have in production. It is, however, supported by major desktop browsers.<br />
Async Call TraceConsole.trace works just fine for normal function calls. In most developer tools, we get the same call trace when we stop on the breakpoint. When the call is async(callback) this information is not available because the scope of the closure(callback function) is limited to the data that it holds. Fortunately, in the newer version of Chrome dev tools we have the flag async. So what previously would have been a portion of the call information...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCo4YsDZpru_bnOWj5F6nPnQj7VAwLybhAp85GACfd6CXjGtGzoLit2sRwBs6U9Dck_4uonyxhrWp4QJkznnFG9V7_zgLXfNxWkmASKlxfqecKWfc21SOY43E_Vk9RViflQkuRhSI-yCM/s1600/Screen-Shot-2014-11-26-at-17.18.12.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCo4YsDZpru_bnOWj5F6nPnQj7VAwLybhAp85GACfd6CXjGtGzoLit2sRwBs6U9Dck_4uonyxhrWp4QJkznnFG9V7_zgLXfNxWkmASKlxfqecKWfc21SOY43E_Vk9RViflQkuRhSI-yCM/s1600/Screen-Shot-2014-11-26-at-17.18.12.png" height="177" width="320" /></a></div>
<br />
<br />
...now becomes a full call trace containing the scope of the caller and the callback:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQhpoJq-VrFvxf8o9-6obK5Up4y1YW54KVxta8Hbk-qbkMNFSVe48z-Os8240DKJhRaQTqSYNLapRuQpEyLKDqOdBoUoIeDtQqS7BqCRiEPA6o8u8wz7OGYSTgDr67uqc-gdQCLzeBvSY/s1600/Screen-Shot-2014-11-26-at-17.18.59.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQhpoJq-VrFvxf8o9-6obK5Up4y1YW54KVxta8Hbk-qbkMNFSVe48z-Os8240DKJhRaQTqSYNLapRuQpEyLKDqOdBoUoIeDtQqS7BqCRiEPA6o8u8wz7OGYSTgDr67uqc-gdQCLzeBvSY/s1600/Screen-Shot-2014-11-26-at-17.18.59.png" height="320" width="281" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
Most definitely an essential feature in today's asynchronous world, in my opinion. For an extensive explanation of how the async call trace works, I recommend <a href="http://www.html5rocks.com/en/tutorials/developertools/async-call-stack/">this</a> HTML5rocks article.<br />
<h3>
Who’s Changing My Object?: Objects.observe + console.trace</h3>
Sometimes objects get some of their properties changed, but we cannot figure out the cause. In this case, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe">objects.observe</a> comes to the rescue. Let's say we want to check for all changes to our person object:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfyavchN9ytODhybWo-NOcZDaM8QSTpkRAo4DRbhUPeL2Chb3jW42HID6O_fZuLys_UVJkheIYdxsV9qbbvXVUEcSHSXX1uxwwjLygl9adbl0-jJJH1M6F8oRLl0Hy6J2PH1beI0rcz8E/s1600/Screen-Shot-2014-11-26-at-17.19.45.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfyavchN9ytODhybWo-NOcZDaM8QSTpkRAo4DRbhUPeL2Chb3jW42HID6O_fZuLys_UVJkheIYdxsV9qbbvXVUEcSHSXX1uxwwjLygl9adbl0-jJJH1M6F8oRLl0Hy6J2PH1beI0rcz8E/s1600/Screen-Shot-2014-11-26-at-17.19.45.png" height="210" width="640" /></a></div>
<br />
<br />
Since we have combined this with the console.trace, we can also see the call trace. Awesome right?<br />
<br />
Well, not so much, since at the time of writing only Chrome supports this and it is a non-standard functionality. Fortunately, it is proposed as part of <a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe">ECMAscript 7</a>. There is also a similar internal variant for this in Gecko based browser <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch">object.watch</a>. Then again, when it comes to debugging, anything we can get is useful. Note that Objects.observe primary function is not debugging, but it is a great side effect.<br />
<h3>
Who’s Changing My DOM/HTML Element - Aka, Who’s F***ing Up My Code?</h3>
<br />
In complex applications, we may end up in a situation where we do not know how a certain HTML element got changed, moved, added, or had some of it's attributes modified. One way to figure out is to attach the now deprecated <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events">mutation event</a> listeners. The API for this is far from ideal, and there are other shortcomings. The <a href="http://caniuse.com/#feat=mutationobserver">newer</a> browser version comes with an object called <a href="https://developer.mozilla.org/en/docs/Web/API/MutationObserver">MutationObserver</a>, which enables us to watch a certain DOM element.<br />
<br />
Suppose we wanted to list all mutations on the entire document, where the document can also be any DOM element selected:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvT2m1vlGL46WKCoUfkS8znKVsD5l0ZehniW9yZugrcad7tfoEWRgvg3PfkLgLwMCLBFi61z1jfDae_aXi6CLN66CMXRF4FA_nmf43jsrf47-q9_Vcnj9cypusvMeKGMBcls1QjTtgod4/s1600/Screen-Shot-2014-11-26-at-17.20.25.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvT2m1vlGL46WKCoUfkS8znKVsD5l0ZehniW9yZugrcad7tfoEWRgvg3PfkLgLwMCLBFi61z1jfDae_aXi6CLN66CMXRF4FA_nmf43jsrf47-q9_Vcnj9cypusvMeKGMBcls1QjTtgod4/s1600/Screen-Shot-2014-11-26-at-17.20.25.png" height="168" width="640" /></a></div>
<br />
<br />
There is also the non-programmable solution we can use in Chrome called <a href="https://chromedevtools.googlecode.com/svn-history/r421/trunk/tutorials/breapoints/index.html#dom">DOM breakpoints</a> which still uses mutation events in the background.<br />
<h3>
Server Side Logging of Client Side Errors</h3>
<br />
As simple as that, just add the error handler to the window object and you're done with the client side. The handler can then make an AJAX request to a REST endpoint which will store the error information on your server. You might find out that a client using IE 8 has a lot of issues this way because IE versions predating 9 have no <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim">string.trim()</a>. I guess string trim is just not that essential.<br />
<br />
Anyway, this what the most basic server side logging of client side errors might look like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF6Awk3kdmVggJyR-o4DEVuvO2LvROwIQm7nGtIRzQtK57zKp5VipfE4vZV5wdK8itvPqtWpTIHEwdc7pNE55nrN10VZslRwcpBUVJ7RFxMuTFy5gVsZabtGS0pbE7K1IWh8amMfAzQaM/s1600/Screen-Shot-2014-11-26-at-17.22.16.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF6Awk3kdmVggJyR-o4DEVuvO2LvROwIQm7nGtIRzQtK57zKp5VipfE4vZV5wdK8itvPqtWpTIHEwdc7pNE55nrN10VZslRwcpBUVJ7RFxMuTFy5gVsZabtGS0pbE7K1IWh8amMfAzQaM/s1600/Screen-Shot-2014-11-26-at-17.22.16.png" height="202" width="640" /></a></div>
<br />
Of course, this is the most basic of solution you can have. There are tons of better solutions out there like <a href="http://www.stacktracejs.com/">http://www.stacktracejs.com/</a> or <a href="http://jsnlog.com/">http://jsnlog.com/</a> and a more extensive article on <a href="https://hacks.mozilla.org/2014/08/javascript-error-and-xhr-log-recording-with-every-bug-report/">Mozilla hacks</a>. There is also a great <a href="https://news.ycombinator.com/item?id=3796869">Hacker News</a> discussion on this topic, but hey, this is certainly a good start!<br />
Use Google Or Other Analytics Tools to Store Data<br />
<br />
<br />
<br />
I know you are way too busy to be writing any backend code. so why not just store the data in Google Analytics?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfQ7RrJnnI3KxSLngYL3KnQu2BzJ619jPQcTMX-Kn1IbBK_kS5u8tfpETr9CexnOGHd4lpQYKosgYLwB-QGy-41h9B53QI6R7Sj28ncEWPTA0SVM2htPjPViauAd80rw8nMcpn-Rc-wbk/s1600/Screen-Shot-2014-11-26-at-17.23.15.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfQ7RrJnnI3KxSLngYL3KnQu2BzJ619jPQcTMX-Kn1IbBK_kS5u8tfpETr9CexnOGHd4lpQYKosgYLwB-QGy-41h9B53QI6R7Sj28ncEWPTA0SVM2htPjPViauAd80rw8nMcpn-Rc-wbk/s1600/Screen-Shot-2014-11-26-at-17.23.15.png" height="90" width="640" /></a></div>
<br />
<br />
You can certainly do this, but note that this is a hack, and there are a lot of better commercial options out there like <a href="http://usersnap.com/">http://usersnap.com</a> if you want to be really thorough - but even a hack is better than no information, which is what most people have.<br />
<h3>
So, You Don’t Think JavaScript is “Real” Code?</h3>
<br />
<a href="https://www.voxxed.com/wp-content/uploads/2014/11/Screen-Shot-2014-11-26-at-17.23.54.png"><img src="https://www.voxxed.com/wp-content/uploads/2014/11/Screen-Shot-2014-11-26-at-17.23.54-210x300.png" /></a></div>
<div>
<br /></div>
<div>
I had been mulling over this idea for a long time, when, a few years back, I realized that I was making a huge mistake in my approach to JavaScript. You should take it just as seriously as Java, C# or Ruby.<br />
<br />
Diseases are something you pick up, JavaScript is something you have to learn.<br />
<br />
Just like other programming languages, you need a <a href="https://amzn.to/37X40vK">book</a>, programming exercises and multiple projects. JavaScript also needs coding style guides, <a href="http://karma-runner.github.io/0.12/index.html">testing</a> frameworks, and code <a href="http://www.jshint.com/about/">analysis</a>, and so on. Basically everything that you have a "real code". There are complete solutions like <a href="http://yeoman.io/">Yeoman</a> and <a href="https://jhipster.github.io/">JHipster</a> that will help you with full integration.<br />
<br />
Unless you do this, you will always end up hating JavaScript - which is a shame considering that JavaScript is all around you! If you follow best practices, most of the time you won't be debugging any code nor resorting to clever tricks. Unless you’re Chuck, that is.<br />
<br />
<h3>
More Resources:</h3>
<a href="https://github.com/DeveloperToolsWG/console-object/blob/master/api.md">https://github.com/DeveloperToolsWG/console-object/blob/master/api.md</a><br />
<a href="https://developer.chrome.com/devtools#debugging-javascript">https://developer.chrome.com/devtools#debugging-JavaScript</a><br />
<a href="https://developer.mozilla.org/en-US/docs/Tools/Debugger">https://developer.mozilla.org/en-US/docs/Tools/Debugger</a><br />
<a href="http://msdn.microsoft.com/en-us/library/dd565625%28v=vs.85%29.aspx">http://msdn.microsoft.com/en-us/library/dd565625%28v=vs.85%29.aspx</a><br />
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript">https://developer.mozilla.org/en-US/docs/Web/JavaScript</a><br />
<a href="http://www.html5rocks.com/">www.HTML5rocks.com</a><br />
<br />
<br />
<br />
<br /></div>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-85331856340882399932014-11-25T01:14:00.001+01:002020-11-09T17:48:44.853+01:00Java2Days 2014: From JavaSpaces, JINI and GigaSpaces to SpringBoot, Akka – reactive and microservice pitfallsThis my 5-th year in a row where together with <a href="http://www.jug.mk/">jugmk</a> attend <a href="http://2014.java2days.com/">Java2days</a>, a conference in Sofia, Bulgaria. While not so obvious from the name it is a 2-day java conference and currently the biggest one near us that we can take a bus to go to.<br />
This year I had a talk titled <i>"From JavaSpaces, JINI and GigaSpaces to SpringBoot, Akka – reactive and microservice pitfalls."</i><br />
or buzz words and hate words all in one.<br />
<br />
<h3>
About the topic </h3>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAfg7FoQjhfG2vqDBut5M9lux1R1KrLyJveSioFvurGKDwqO_Sz-U0JMpsqI4WLlmxY728Zvpf0kBceM6io3QYJwap816OHRn6RgULzkhAnFHc7NABMj6MB2g3KHcCROUt4SCpkpSFlb8/s1600/DSC_0160.JPG" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAfg7FoQjhfG2vqDBut5M9lux1R1KrLyJveSioFvurGKDwqO_Sz-U0JMpsqI4WLlmxY728Zvpf0kBceM6io3QYJwap816OHRn6RgULzkhAnFHc7NABMj6MB2g3KHcCROUt4SCpkpSFlb8/s1600/DSC_0160.JPG" height="425" width="640" /></a><br />
My talk this year was about microservices even though it had a long title with lots of strange words it was more of a concepts talk.<br />
I gave a basic introduction into what reactive programming means for different people, the <a href="http://www.reactivemanifesto.org/">reactive manifesto</a> and of course Microsoft Excel.<br />
<table align="center" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTu9CaGN5I-sIOxigicIAW94ugocKTDxZI6FgMvvB5v3da8zoYRWwSq4oWC2Xdol-svlyPSkvApxZhVusnF5cHR6RV08aqGoLo7CiZiwWoLJNfp9U6oV9RGMagbc6stIaXWCYc2Ft2NvA/s1600/me3.jpg" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTu9CaGN5I-sIOxigicIAW94ugocKTDxZI6FgMvvB5v3da8zoYRWwSq4oWC2Xdol-svlyPSkvApxZhVusnF5cHR6RV08aqGoLo7CiZiwWoLJNfp9U6oV9RGMagbc6stIaXWCYc2Ft2NvA/s1600/me3.jpg" height="426" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Long title = crowds of attendees</td></tr>
</tbody></table>
Next part was to define what microservies are and what they can be for different organization.<br />
The Unix aspect of microservices had to be covered so I did just that.<br />
<br />
My goal with the talks was not really to compare frameworks for this or that, but I just gave a short overview of what ideas are behind the development of some libraries.<br />
<br />
The last major section was the real conclusion phase called how not to fail at microservices.<br />
I gave some recommendations from my personal experience as well as references to important books on the subject.<br />
One of them available on early access:<br />
<br />
<div style="text-align: center;">
<a href="http://www.amazon.com/gp/product/1491950358/ref=as_li_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1491950358&linkCode=as2&tag=mitemitreskic-20&linkId=X6CKDX3PHBXQD6IP"><img border="0" src="http://ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=1491950358&Format=_SL250_&ID=AsinImage&MarketPlace=US&ServiceVersion=20070822&WS=1&tag=mitemitreskic-20" height="400" width="304" /></a><img alt="" border="0" src="http://ir-na.amazon-adsystem.com/e/ir?t=mitemitreskic-20&l=as2&o=1&a=1491950358" height="1" style="border: none !important; margin: 0px !important;" width="1" />
</div>
<br />
And also the famous Release It book which covers some of the scenarios that are essential for microservice development.<br />
<div style="text-align: center;">
<a href="http://www.amazon.com/gp/product/0978739213/ref=as_li_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0978739213&linkCode=as2&tag=mitemitreskic-20&linkId=7MOZRVSHRRLQ4EWW"><img border="0" src="http://ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=0978739213&Format=_SL250_&ID=AsinImage&MarketPlace=US&ServiceVersion=20070822&WS=1&tag=mitemitreskic-20" /></a><img alt="" border="0" src="http://ir-na.amazon-adsystem.com/e/ir?t=mitemitreskic-20&l=as2&o=1&a=0978739213" height="1" style="border: none !important; margin: 0px !important;" width="1" />
</div>
My main take out from the talk was:<br />
<blockquote class="tr_bq">
Don't fall for the hype and make sure you start small and then grow. If your team and operations can handle it then increase the granularity. </blockquote>
<br />
Here are the full slides of the talk:<br />
<br />
<br />
<br />
<div style="margin-bottom: 5px;">
<strong> <a href="https://www.slideshare.net/mitemitreski1/microservice-pitfalls" target="_blank" title="Microservice pitfalls ">Microservice pitfalls </a> </strong> from <strong><a href="https://www.slideshare.net/mitemitreski1" target="_blank">Mite Mitreski</a></strong> <br />
<br />
<br />
<h3>
The conference </h3>
<br />
As for the full conference it was great to meet up with BG-JUG folks like Ivan St. Ivanov, Mihail Stoynov, Martin Tosev and improve the cooperation between JUGMK and BG-JUG.<br />
There were also the standard visitor's Josh Long and Andrew Lombardi who are there to stay :<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhho4mqS0tU8Oy4sYK0TToKSoLq-WePBcpmtFpLhHnxYU7_a83QsrUffkOs2B2-ZFESj98wkFpmoF480v2X7ojAwj5q0ZzOZYqc0coI6xPQ_qLPHwKV6a36vzQbZJWwZVBQjpW2J8hBLu0/s1600/me2.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhho4mqS0tU8Oy4sYK0TToKSoLq-WePBcpmtFpLhHnxYU7_a83QsrUffkOs2B2-ZFESj98wkFpmoF480v2X7ojAwj5q0ZzOZYqc0coI6xPQ_qLPHwKV6a36vzQbZJWwZVBQjpW2J8hBLu0/s1600/me2.jpg" height="426" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
I got to meet with John Davis and learn how others use archaic tuple space technologies and how the banking world functions. Overall it was a great experience and even though at time some of the conference topics were overly light or outdated for my taste but the social aspect of it was more than sufficient to cover any shortcomings on the technical side.<br />
For example Mani Sarkar had a great talk on "Learning the two Ts", it was great to meet up with him as well.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4u5otWDfWAF36iELh83Vm1-tDNc4KKvvJBqJOL6Urq6R9SPjdnybV9-_n_ybX_9DtifyoijBKcLF-OoUseZh4wRSTt2dQFRpPspV9KifS6RDq3r2SMTwlJrkVzjQOT4HMl3Fir2KigqE/s1600/DSC_0142.JPG" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4u5otWDfWAF36iELh83Vm1-tDNc4KKvvJBqJOL6Urq6R9SPjdnybV9-_n_ybX_9DtifyoijBKcLF-OoUseZh4wRSTt2dQFRpPspV9KifS6RDq3r2SMTwlJrkVzjQOT4HMl3Fir2KigqE/s1600/DSC_0142.JPG" height="425" width="640" /></a><br />
<br />
One other positive trend that is happening this year is we had record number of JUGMK speakers and participants on Java2Days. The same trend is also on other conferences and is a great thing to see.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidoCgRAjDsbvAuFm05aF-RA4OiPHKSpfhgSmMVSrm9C9sCMx-QrNA8eOJBw4_3WpUCsSrxStMtD9V0lwYedSKL9yfsURyoWPqgi1OHmDsI_om3FRpozLuw_clzMhpWZVGN_sILiZRDV_A/s1600/me.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidoCgRAjDsbvAuFm05aF-RA4OiPHKSpfhgSmMVSrm9C9sCMx-QrNA8eOJBw4_3WpUCsSrxStMtD9V0lwYedSKL9yfsURyoWPqgi1OHmDsI_om3FRpozLuw_clzMhpWZVGN_sILiZRDV_A/s1600/me.jpg" height="426" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">The JUG Factor</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I know I'm forgetting someone to mentions, but overall an interesting social experience and a great meetup. </div>
<br /></div>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-60735288849220944772014-04-13T22:36:00.002+02:002020-11-09T17:48:56.209+01:00Virtual Java User Group - simple concept with quality content<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbYil-eGP9q6XtzYsIGapENsBSyYmsBLLoAk0shtsQ_7GgW58conXMId8yPxha8NmfM42aprvoQCA3GcJfakHIXYqnG8tBa25O1TvsAqc2Cs9LrLQnSFC_bYE2v4zhYFOdfNQibEfwoCc/s1600/vjug.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbYil-eGP9q6XtzYsIGapENsBSyYmsBLLoAk0shtsQ_7GgW58conXMId8yPxha8NmfM42aprvoQCA3GcJfakHIXYqnG8tBa25O1TvsAqc2Cs9LrLQnSFC_bYE2v4zhYFOdfNQibEfwoCc/s1600/vjug.jpg" height="194" width="320" /></a></div>
<a href="http://www.meetup.com/virtualJUG/" target="_blank">Virtual JUG</a> is a simple concept based on the idea to organize a group that would generate quality content.<br />
<div>
It is simpler to get technical leaders from around the world to present online and there are no travel cost concerns. The intent is not to replace local JUG's but rather increase their value and also represent a sort of global JUG. Additionally it enables developers without an access to a local jug with a means to connect with many developers around the world.</div>
<div>
<div style="border: 0px; margin: 0px 0px 5px; overflow: hidden; padding: 0px; text-overflow: ellipsis; word-wrap: normal;">
<br />
<br /></div>
<div style="border: 0px; margin: 0px 0px 5px; overflow: hidden; padding: 0px; text-overflow: ellipsis; word-wrap: normal;">
Live sessions are streamed online and as chat <b>##virtualJUG </b>on Freenode is used. But you don't have to trust my word for the quality of the content, here is a list of the past sessions: </div>
<div style="border: 0px; margin: 0px 0px 5px; overflow: hidden; padding: 0px; text-overflow: ellipsis; word-wrap: normal;">
<span dir="ltr" title=""Design is a Process, not a Document" by Trisha Gee"><br /></span></div>
<ul>
<li>"<a href="https://www.youtube.com/watch?v=GixwXNlZ7dI">Design is a Process, not a Document</a>" by Trisha Gee</li>
<li>"<a href="https://www.youtube.com/watch?v=0Iq0pI259yk">Drive by Contributions</a>" A GitHub session by Brent Beer and Matthew McCullough</li>
<li>"<a href="https://www.youtube.com/watch?v=uKy6wAeaPEU">Don't be that guy! Developer Security Awareness</a>" by Markus Eisele</li>
<li>"<a href="https://www.youtube.com/watch?v=M87rQp74WUE">Getting Started with Java EE 7</a>" by Arun Gupta</li>
<li>"<a href="https://www.youtube.com/watch?v=QCnzefe72rg">How To Do Kick-Ass Software Development</a>" by Sven Peters</li>
<li>"<a href="https://www.youtube.com/watch?v=rtAredKhyac">55 New Features in Java SE 8</a>" by Simon Ritter</li>
<li>"<a href="https://www.youtube.com/watch?v=ygW8fJVlDxQ">Comparing JVM Web Frameworks</a>" by Matt Raible</li>
<li>"<a href="https://www.youtube.com/watch?v=lbANLOUFe58">WebSocket Applications using Java EE 7</a>" by Arun Gupta</li>
<li>"<a href="https://www.youtube.com/watch?v=Std4TEmBdTM">Project Lambda: Functional Prog. Constructs and Simpler Concurrency in Java SE</a>" by Simon Ritter</li>
<li>"<a href="https://www.youtube.com/watch?v=LRh0nDuYCyY">Java 8 Parallel Streams Workshop</a>" by Stuart Marks</li>
<li>"<a href="https://www.youtube.com/watch?v=eCos5VTtZoI">Building 'Bootiful' Applications with Spring Boot</a>" by Josh Long by Josh Long</li>
</ul>
<div>
<br /></div>
<div>
Many thanks to <a href="https://twitter.com/sjmaple" target="_blank">Simon Maple</a> the organizing team <a href="http://www.meetup.com/virtualJUG/members/12218326/">Anton Arhipov</a>, <a href="http://www.meetup.com/virtualJUG/members/111687032/">Geert Bevin</a>, <a href="http://www.meetup.com/virtualJUG/members/7844866/">James Gough</a>, <a href="http://www.meetup.com/virtualJUG/members/111686482/">Oliver White</a>. Keep up the good work. </div>
<br />
<br />
<h1 style="background-color: white; color: #222222; font-family: arial, sans-serif;">
<span dir="ltr" title=""Drive by Contributions" A GitHub session by Brent Beer and Matthew McCullough"></span></h1>
</div>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-76448004488247325192014-04-09T20:39:00.002+02:002020-11-09T22:21:59.612+01:00*nix for developersUnix and Linux in their various forms are everywhere. Werther you are working on some server-side application or mobile app at any stage it is very likely that it will use Unix at some point.<br />
That is why at our company we decided to have a small introduction demo/discussion on some useful concepts and command line tools.<br />
We also went through a high-level overview starting with <a href="http://en.wikipedia.org/wiki/Init" target="_blank">initial</a> with <a href="http://en.wikipedia.org/wiki/Runlevel" target="_blank">run level</a> and <a href="http://en.wikipedia.org/wiki/Job_control_%28Unix%29" target="_blank">job control</a>.<br />
While most of the demoing is not visible via the slides I decided to share the slides anyway:<br />
<br />
<br />
<div style="margin-bottom: 5px;">
<strong> <a href="https://www.slideshare.net/mitemitreski1/unix-for-devlopers" target="_blank" title="Unix for devlopers">Unix for developers</a> </strong> from <strong><a href="http://www.slideshare.net/mitemitreski1" target="_blank">Mite Mitreski</a></strong> </div>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-66818369023517045612014-03-03T22:40:00.002+01:002020-11-09T22:22:07.264+01:00Redneck conditional anti-pattern<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijLlvL5IgJzTQMkqyCrV5zb8cWP2qisVbPIV7ctKrbv6TASG3w-GLpmUg-i-Vz_EgcipU7QbLSKkqSLDoFWsqa6_7IGLx0mS11llid5qALb3eBT6_eNF0XDk0E8hHA3_4_99HopLqx4_8/s1600/Almost+Politically+Correct+Redneck.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijLlvL5IgJzTQMkqyCrV5zb8cWP2qisVbPIV7ctKrbv6TASG3w-GLpmUg-i-Vz_EgcipU7QbLSKkqSLDoFWsqa6_7IGLx0mS11llid5qALb3eBT6_eNF0XDk0E8hHA3_4_99HopLqx4_8/s1600/Almost+Politically+Correct+Redneck.jpg" height="181" width="320" /></a></div>
<h3 id="the-background">
</h3>
Sometimes I encounter weird looking <code>if</code> statements. By weird, I'm thinking of multiple negations all over the code base. Just a few days ago together with my colleague we found them very exotic during debug of an external library. From this point on, I'll call the following anti-pattern redneck negation or "I ain't not going to do that".<br />
<br />
<br />
<br />
So let's take a look at a snippet:<br />
<pre><code>if(!some_flag_that_means_off) {
//handle negative scenario where we change the flag value
} else {
//handle positive scenario where we also change the flag value
}
//decide upon my flag</code></pre>
The simpler version would be an extracted method with:<br />
<pre><code> if(some_condition) {
//return positive
} else {
//return negative
}</code></pre>
Now the code is easier to read and simpler to maintain.<br />
<br />
<h3 id="state-of-mind">
State of mind</h3>
You might be wondering how someone writes this or how we end up with this type of multiple negation codes. It is easy to judge people, but the reality is that this might have been done at some crazy pressure to "save time". It is possible the programmer working on this part was solving some bug and did not consider the readability. It could be also the lack of knowledge or attention or maybe cosmic rays. No matter the reasoned judgment is not the answer.<br />
<br />
I once had a discussion with a friend about a related topic and he said on his team they have banned the debugger. This might seem crazy at first, but when you think about it, we usually add various redundant <code>if</code>'s during debugging. We add them without seeing the bigger picture and that is one other way we can end up with conditionals all over the place. Now his argument against the debugger looks less crazy.<br />
<br />
While not all <code>if</code>'s are made the same, the vast majority of them can be avoided and the complexity they bring with them. Of course, this is a broader topic but it is something to keep in mind.<br />
<br />
<h3 id="how-do-we-fix-this">
How do we fix this?</h3>
Even though this should be simple enough to change I would first start with the following:<br />
<blockquote>
Whenever I do refactoring, the first step is always the same. I need to build a solid set of tests for that section of code. The tests are essential because even though I follow refactorings structured to avoid most of the opportunities for introducing bugs, I'm still human and still make mistakes. Thus I need solid tests.<br />
Martin Fowler - <a href="https://amzn.to/2TFAZfK">Refactoring: Improving the Design of Existing Code</a></blockquote>
It is truly one of the best advice someone can give you before you start refactoring. The statement switch from negative to positive should be simple enough to start off with. Then again, it should be simple enough to not even introduce this but that is obviously not the case.<br />
Next step would be to remove the changing of the flag either by extracting this into a separate method or even possibly removing it altogether.<br />
<br />
There are plenty of options in the simplification of the conditionals. One way is to [replace conditional] with polymorphism. There is a great talk by <a href="http://misko.hevery.com/about/">Misko Hervey</a> part of the Google Clean Code Talks titled <a href="http://www.youtube.com/watch?v=4F72VULWFvc">"Inheritance, Polymorphism, & Testing"</a>. Also, we can run into the conditionals <a href="http://c2.com/cgi/wiki?ArrowAntiPattern">arrow anti-pattern</a> and the related text from Jeff Atwood titled <a href="http://blog.codinghorror.com/flattening-arrow-code/">Flattening Arrow Code</a>.<br />
<br />Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-86821352734820216212014-02-22T00:11:00.003+01:002020-11-09T22:22:21.637+01:00[Book review] OAuth 2.0 Identity and Access Management Patterns<a href="https://amzn.to/2Jqkcvz" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=1783285591&Format=_SL160_&ID=AsinImage&MarketPlace=US&ServiceVersion=20070822&WS=1&tag=mitemitreskic-20" /></a><img alt="" border="0" src="http://ir-na.amazon-adsystem.com/e/ir?t=mitemitreskic-20&l=as2&o=1&a=1783285591" height="1" style="border: none !important; margin: 0px !important;" width="1" /><br />
I accepted to do a review of the newly published <a href="http://www.amazon.com/gp/product/1783285591/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1783285591&linkCode=as2&tag=bestforblackfriday-20">OAuth 2.0 Identity and Access Management Patterns</a> by <a href="http://blog.thisismartin.com/">Martin Spasovski</a>. He is a friend of mine so with impartiality in mind it would be fail enough of me to give this information beforehand.<br />
<br />
<a href="http://oauth.net/2/">OAuth</a> is the most widely known and used authorization framework. There are many service providers like Facebook and Twitter making it easy to connect with millions of users. From the users perspective is significantly simpler than remember and managing different passwords which is easily manipulated. The book make nice introduction to integration of OAuth 2.0 on web applications, desktop and mobile. It also covers various flows and a server side implementation using SpringMVC. While the examples throughout the book are clean one part really caught my attention :<br />
<pre><code> tokenEndpoint
.concat("?grant_type=client_credentials")
.concat("&client_id=").concat(clientId)
.concat("&client_secret=").concat(clientSecret)
.concat("&user_id=").concat(user_id)</code></pre>
Concatenating strings using <code>String.concat</code> is something I would consider a premature optimization for speed. Much cleaner way would be the regular <code>+</code> based concatenation or even maybe <code>String.format</code>. In any case that is something that is probably completely irrelevant and off topic but I just can't help it.<br />
<br />
What I found really interesting is the chapter titled "Additional Security with SAML", mostly because I did not know there is a thing like this out there let alone used it. <a href="http://en.wikipedia.org/wiki/Security_Assertion_Markup_Language">SAML</a> or Security Assertion Markup Language is a XML based protocol for exchange of authentication and authorization data between user and provider where the user can be a provider itself. SAML provides Single Sign-on across multiple domains and identity federation which is useful for many enterprise applications.<br />
<br />
A thing to note is that the proofreader did not made a good job since even me with my many typos and grammar error noticed this. This is a problem I had in <a href="http://html5dsbook.com/" target="_blank">my book</a> and is an issue with most of the Packt publishing books. Some folks on reddit and over the "internets" have claimed that this was the case because most of the authors are non-native english speakers. This is is not be the case since there many non-native authors for other publishers and they do a great job so why can't Packt?<br />
For me this does not affect the overall impression but I know there are some grammar nazi out there.<br />
<br />
One incorrect assumption I made before starting with the book is that it will only cover Java related tooling and implementation. There are sections with references to all major programming languages and various tooling support that will assist you independent from your preferred language.<br />
<br />
To sum it up the book is an awesome reference for OAuth 2.0 and the various pattern for integrating it into your system. I know I will get back to it at some point in the future. You should get it if you expect to do any OAuth integration in the future whether it is server or client side.<br />
<br />
<br />Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-12663977210647843272014-01-20T02:37:00.002+01:002020-11-09T22:22:28.574+01:00"Thou shalt not spam" or what are web notifications<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXuFoIAKJ5WahFv_kYIch2nAidFJBoRqJUyXFagoP4pImYBrqdMp6eoebhxUsZPnpg6p-TpHJjK3cg1KdaIkzVWOR57POyq128y452Zd91D5RPdVr4SmmcA77ZdV0Zlb7o1mYtdPXU4Yw/s1600/notification.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXuFoIAKJ5WahFv_kYIch2nAidFJBoRqJUyXFagoP4pImYBrqdMp6eoebhxUsZPnpg6p-TpHJjK3cg1KdaIkzVWOR57POyq128y452Zd91D5RPdVr4SmmcA77ZdV0Zlb7o1mYtdPXU4Yw/s320/notification.png" /></a></div>
<p>Web notifications are one of the newer features added into modern browsers.
They are intended as alerts for the user outside of the web page context.
The idea is for them to be browsers and system independent, for example, when using a mobile browser notification
could go into the home screen of the device. On the desktop usually they show up on the right-corner of the screen,
at least on most desktop environments.
They can be very annoying thing and you should think if thoroughly before you decide this is the right way to inform the users. There are some restrictions that avoid the creation of popup but I still have a bad feeling whenever I see one of these.
One example of these notifications are the gmail/gtalk updates that show up on new messages (they are useful and annoying at the same time).
This is done via the <a href="http://www.w3.org/TR/notifications/">Notification API</a> and we will do a simple example of its usage.</p>
<h4>The implementation</h4>
<p>First we can start with a simple wrapper for the <a href="http://www.w3.org/TR/notifications/">Notification API</a> that will have a fallback for the WebKit temporary implementation.
We will define a <code>simpleNotification</code> object that will be the wrapper and it will contain a function called <code>show</code> that accepts data parameter.
This data parameter is also a wrapper object that contains all the required info for a simple notification. For example :</p>
<pre><code>var data = {
icon: "http://upload.wikimedia.org/wikipedia/commons/7/7e/Jacob_de_Gheyn_-_Wapenhandelinge_4.jpg",
title: "The Art of War - The Use of Spies ",
body: "text",
timeout : 7000,
errorCallback: function(){
$("#fallback").text(this.body);
}
};
</code></pre>
<p>Where the <code>errorCallback</code> is executed if non of our implementations are supported by the browser, as for the others, they should be self descriptive.</p>
<pre><code>var simpleNotification = (function () {
var my = {};
my.show = function (data) {
if (window.webkitNotifications) {
//check if there is a support for webkitNotifications
if (window.webkitNotifications.checkPermission() == 0) {
var notification = webkitNotifications.createNotification(data.icon, data.title, data.body);
notification.show();
//set timeout to hide it
setTimeout(function(){
notification.cancel();
}, data.timeout);
} else {
webkitNotifications.requestPermission(function () {
//call the same function again
my.show(data);
});
}
}else if (window.Notification) {
//Currently a fallback, but this should be the real implementation on all browsers
if ("granted" === Notification.permissionLevel()) {
var notification = new Notification(data.title, data);
notification.show();
} else if ("default" === Notification.permissionLevel() ) {
Notification.requestPermission(function () {
//call the same function again
my.show(data);
});
}
}else{
//Notifications not supported,going with fallback
data.errorCallback();
}
};
return my;
}());
</code></pre>
<p>The standard based implementation is the one that uses <code>window.Notification</code>. An interface defined by <a href="http://www.w3.org/TR/notifications/">W3C</a></p>
<pre><code> [Constructor(DOMString title, optional NotificationOptions options)]
interface Notification : EventTarget {
static readonly attribute NotificationPermission permission;
static void requestPermission(optional NotificationPermissionCallback callback);
attribute EventHandler onclick;
attribute EventHandler onshow;
attribute EventHandler onerror;
attribute EventHandler onclose;
readonly attribute NotificationDirection dir;
readonly attribute DOMString lang;
readonly attribute DOMString body;
readonly attribute DOMString tag;
readonly attribute DOMString icon;
void close();
};
</code></pre>
<p>Since our <code>data</code> object already contains similar values it can be passed directly in the instantiation of the <code>Notification</code> object.
For example :</p>
<pre><code>var notification = new Notification(data.title, data);
</code></pre>
<p>On the other hand <code>window.webkitNotifications</code> is the non-standard Chrome implementation.
For a more detailed usage of the webkit version please see <a href="http://decadecity.net/blog/2012/10/12/webkit-notification-api">decadecity blogpost</a>.</p>
<p>In order for us to be able to trigger the notification it is important in the html snippet to have some element that can be user triggered.
We have some simple html containing a button</p>
<pre><code> <body>
<button id="show">Show quote</button>
<div id="fallback"> my fallback notification</div>
</body>
</code></pre>
<p>This is needed in order to have request for the permission and to avoid “spam” notification. In our case this is the <code>onClick</code>
function on the button. More specifically the jQuery <code>click</code> event.
The call now is very simple, we just create the <code>data</code> object using some defaults and load some random data.</p>
<pre><code>$(document).ready(function() {
$("#show").click(function () {
var data = {
icon: "http://upload.wikimedia.org/wikipedia/commons/7/7e/Jacob_de_Gheyn_-_Wapenhandelinge_4.jpg",
title: "The Art of War - The Use of Spies ",
body: "text",
timeout : 7000,
errorCallback: function() {
$("#fallback").text(this.body);
}
};
var randomSampleId = Math.floor(Math.random()*sampleData.quotes.length)+1;
var sample = sampleData.quotes[randomSampleId];
for (var key in sample) {
data.title += key;
data.body = sample[key];
}
simpleNotification.show(data);
});
});
</code></pre>
<p>The sample data used is a JSON containing quotes from <a href="https://amzn.to/3mE0quA">“Sun Tzu -The Art of War”</a> which is also
available for for free on <a href="http://www.gutenberg.org/ebooks/132">project gutenberg</a> (win for public domain).
The data is structured in the following format :</p>
<pre><code>var sampleData = {
quotes: [
{
"1": "Sun Tzu said: Raising a host of a hundred thousand men and marching them great distances entails heavy loss on the people and a drain on the resources of the State.The daily expenditure will amount to a thousand ounce of silver. There will be commotion at home and abroad, and men will drop down exhausted on the highways, As many as seven hundred thousand lies will be impededin their labor."
},
{
"2": "Hostile armies may face each other for years, striving for the victory which is decided in a single day.This being so, to remain in ignorance of the enemy's condition simply because one grudges the outlay of a hundred ounces of silver in honors and emoluments, is the height of inhumanity."
}
]
};
</code></pre>
<p>One more thing to note is that Web Notifications were not supported by IE when this article was written.</p>
<p>You can play around with the <a href="http://jsfiddle.net/mitemitreski/k4AHS">jsfiddle</a> to see it in action.</p>
<iframe width="100%" height="300" src="http://jsfiddle.net/mitemitreski/k4AHS/embedded/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<h4>Related links</h4>
<ul>
<li>MDN section of Notification API - <a href="https://developer.mozilla.org/en-US/docs/Web/API/notification">https://developer.mozilla.org/en-US/docs/Web/API/notification</a></li>
<li>W3C specs - <a href="http://www.w3.org/TR/notifications/">http://www.w3.org/TR/notifications/</a></li>
<li>WHATWG live spec - <a href="http://notifications.spec.whatwg.org/">http://notifications.spec.whatwg.org/</a></li>
<li>Browser compatibility - <a href="https://developer.mozilla.org/en-US/docs/Web/API/notification#Browser_compatibility">https://developer.mozilla.org/en-US/docs/Web/API/notification#Browser_compatibility</a></li>
<li>Can I use page - <a href="http://caniuse.com/#feat=notifications">http://caniuse.com/#feat=notifications</a></li>
<li>JS fiddle of the example shown - <a href="http://jsfiddle.net/mitemitreski/k4AHS">http://jsfiddle.net/mitemitreski/k4AHS</a></li>
<li>Also <a href="https://amzn.to/37XPqUH">HTML5 data and services cookbook</a> has a recipe on Web Notifications.</li>
</ul>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-23297555399301999792014-01-08T00:40:00.000+01:002020-11-09T22:22:33.839+01:00 Run, JUnit! Run!!!<em>This blog post is crossposted and originally part of the <a href="http://www.javaadvent.com/2013/12/mani-i-will-mention-you-only-once-i.html" target="_blank">2013</a> edition <a href="http://javaadvent.com/">Java Advent Calendar</a> a lovely initiative from </em><i><a href="http://hype-free.blogspot.com/" target="_blank">Attila-Mihaly Balazs </a>and the Transilvania JUG </i><br />
<br />
JUnit together with JavaScript and SVN are some of the technologies that programmers often start using without even reading a single blog post let alone a book. Maybe this is a good thing since they look simple enough and understandable so we can use them right away without any manuals, but this also means that they are also underused. In this article we will go through some features of JUnit that I consider very useful.<br />
<br />
<h3>
Parameterized tests </h3>
<div>
Sometimes we need to run the same method or functionality with many different inputs and different expected results. One way to do this would be to create separate tests for each of the cases, or you</div>
can use loop but that it would be harder to track down the origin of a possible test failure.<br />
<br />
For example if we have the following value object representing rational numbers:<br />
<code>
</code>
<br />
<pre class="prettyprint"><code>public class RationalNumber {
private final long numerator;
private final long denominator;
public RationalNumber(long numerator, long denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
public long getNumerator() {
return numerator;
}
public long getDenominator() {
return denominator;
}
@Override
public String toString() {
return String.format("%d/%d", numerator, denominator);
}
}
</code></pre>
And we have a service class called <i>App</i> with a method convert that divides the number to a rounded value of 5 decimal :<br />
<code>
</code>
<br />
<pre class="prettyprint"><code>public class App {
/**
* THE Logic
*
* @param number some rational number
* @return BigDecimal rounded to 5 decimal points
*/
public static BigDecimal convert(RationalNumber number) {
BigDecimal numerator = new BigDecimal(number.getNumerator()).
setScale(5, RoundingMode.HALF_UP);
BigDecimal result = numerator.divide(
new BigDecimal(number.getDenominator()),
RoundingMode.HALF_UP);
return result;
}
}
</code></pre>
<code>
</code>
And for the actual <i><b>AppTest</b></i> class we have<br />
<code>
</code>
<br />
<pre class="prettyprint"><code>@RunWith(Parameterized.class)
public class AppTest {
private RationalNumber input;
private BigDecimal expected;
public AppTest(RationalNumber input, BigDecimal expected) {
this.input = input;
this.expected = expected;
}
@Parameterized.Parameters(name = "{index}: number[{0}]= {1}")
public static Collection<Object> data() {
return Arrays.asList(new Object[][]{
{new RationalNumber(1, 2), new BigDecimal("0.50000")},
{new RationalNumber(1, 1), new BigDecimal("1.00000")},
{new RationalNumber(1, 3), new BigDecimal("0.33333")},
{new RationalNumber(1, 5), new BigDecimal("0.20000")},
{new RationalNumber(10000, 3), new BigDecimal("3333.33333")}
});
}
@Test
public void testApp() {
//given the test data
//when
BigDecimal out = App.convert(input);
//then
Assert.assertThat(out, is(equalTo(expected)));
}
}
</code></pre>
<code>
</code>
<br />
<br />
The Parametrized runner or <i><b>@RunWith(Parameterized.class) </b></i> enables the "parametrization" or in other words the injection of the collection of values annotated with <i><b>@Parameterized.Parameters</b></i> into the Test constructor where each of the sublist is an parameter list. This means that each of the <i><b>RationalNumber</b></i> objects in the <i><b>data()</b></i> method will be injected into the input variable and each of the BigDecimal values would be the expected value, so in our example we have 5 tests.<br />
<br />
There is also an optional custom naming of the generated test added in the annotation, so "<i><b>{index}: number[{0}]= {1}</b></i>" will be replaced with the appropriate parameters defined in the <b><i>data()</i></b> method and the <b>"{index}"</b> placeholder will be the test case index, like in the following image<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9yIXuA1gyYHQ40abQ1HViefo2t5yIfOEtl0Z5UxngxWs-d32V6TN2Q6kyTUj8k9AxIfKDofAbiLIB4k3GousCoVNZKy_zS0Jkm2K-6Zl4zeZWxvfG8Ri_sqQdd0qZTvy78GcLKBQI4KIx/s1600/service.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9yIXuA1gyYHQ40abQ1HViefo2t5yIfOEtl0Z5UxngxWs-d32V6TN2Q6kyTUj8k9AxIfKDofAbiLIB4k3GousCoVNZKy_zS0Jkm2K-6Zl4zeZWxvfG8Ri_sqQdd0qZTvy78GcLKBQI4KIx/s640/service.png" height="176" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Running the parametrized tests in IntelliJ Idea </td></tr>
</tbody></table>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<h3>
<b>JUnit rules</b></h3>
The simplest definition of JUnit rules is that they are in a sense an interceptors and very similar to the Spring aspect oriented programming or Java EE interceptors API. Basically you can do useful things before and after the test execution. <br />
OK so let's start with some of the built in test rules. One of them is <b><i>ExternalResource</i></b> where the idea is that we setup an external resource and after the teardown garteet the resource was freed up. A classic example of such test is a creation of file, so for that purpose we have a built in class <b>TemporaryFolder</b> but we can also create our own ones for other resources :<br />
<br />
<br />
<pre class="prettyprint"><code>
public class TheRuleTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test
public void someTest() throws IOException {
//given
final File tempFile = folder.newFile("thefile.txt");
//when
tempFile.setExecutable(true) ;
//then
assertThat(tempFile.canExecute(), is(true));
}
}
</code></pre>
We could have done this in a <b>@Before</b> and <b>@After </b>blocks and use <a href="http://blog.mitemitreski.com/2012/11/temporary-directories-in-java-7-and.html#.UqEqkB9OVCI">java temp files</a> but it is easy to forget something and leave some of the files unclosed in some of the scenarios where a test fails.<br />
<br />
For example there is also a Timeout rule for methods where if the the execution is not finished in given time limit the test will fail with a Timeout exception. For example to limit the running for 20 milliseconds :<br />
<br />
<code></code><br />
<pre class="prettyprint"><code>@Rule
public MethodRule globalTimeout = new Timeout(20);
</code></pre>
<br />
We can implement our own rules that can do a policy enforcement or various project specific changes. The only thing that needs to be done is for us to implement the TestRule interface.<br />
A simple scenario to explain the behaviour is to add a rule that prints someting before and after test.<br />
<br />
<code></code><br />
<pre class="prettyprint"><code>import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class MyTestRule implements TestRule {
public class MyStatement extends Statement {
private final Statement statement;
public MyStatement(Statement statement) {
this.statement = statement;
}
@Override
public void evaluate() throws Throwable {
System.out.println("before statement" );
statement.evaluate();
System.out.println("after statement");
}
}
@Override
public Statement apply(Statement statement,
Description description) {
System.out.println("apply rule");
return new MyStatement(statement);
}
}
</code></pre>
<br />
So now that we have our rule we can use it in tests, were the tests will just print out different values:<br />
<pre class="prettyprint"><code>
public class SomeTest {
@Rule
public MyTestRule folder = new MyTestRule();
@Test
public void testA() {
System.out.println("A");
}
@Test
public void testB() {
System.out.println("B");
}
}
</code></pre>
When we run a test the following output will be created on the console output :<br />
<pre class="prettyprint"><code>
apply rule
before statement
A
after statement
apply rule
before statement
B
after statement</code></pre>
From the built in one there is one called <b><i>ExpectedException</i></b> that can very useful when trying out testing errors. Additionally there is an option to chain the rules that can be useful in many scenarios.<br />
<br />
<div>
<h3>
To sum up</h3>
If you wanna say that <a href="https://code.google.com/p/spock/">Spock</a> or <a href="http://testng.org/">TestNG</a> or some library build on top of JUnit have more features than JUnit, than that is probably true.<br />
But you know what? We don't always have those on our class path and chances are that JUnit is there and already used all over the place. Than why not use it's full potential ?<br />
<h4>
<br />Useful links</h4>
<ul>
<li>Restrictions and details about parametrized tests as well as indexing of attributes and removing the constructor - <a href="https://github.com/junit-team/junit/wiki/Parameterized-tests">https://github.com/junit-team/junit/wiki/Parameterized-tests</a></li>
<li>JUnit Rules - <a href="https://github.com/junit-team/junit/wiki/Rules">https://github.com/junit-team/junit/wiki/Rules</a></li>
<li>Devoxx talk on JUnit Rules <a href="http://www.devoxx.com/display/DV12/JUnit+Rules">http://www.devoxx.com/display/DV12/JUnit+Rules</a></li>
<li>TestNP parameters <a href="http://testng.org/doc/documentation-main.html#parameters">http://testng.org/doc/documentation-main.html#parameters</a></li>
<li>Mixing it up with Spring Runner <a href="http://java.dzone.com/articles/writing-parameterized-tests">http://java.dzone.com/articles/writing-parameterized-tests</a></li>
</ul>
</div>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-3873032842158765512013-12-31T00:16:00.003+01:002020-11-09T22:24:10.427+01:00Cliché all the way or "Year in review vs the Future"<p>Inspired by <a href="http://www.javaadvent.com/2013/12/2013-javajvm-year-in-review-and-look-to.html"> Martijn Verburg article </a> on Java/JVM year in review I decided to write my own version of some public and some more personal events that happened during the past year. My idea is also to add some cliché section in the style of "New Year Resolutions".</p>
<h3>Looking back at 2013</h3>
<p>This has been quite an eventful year for me.</p>
<h4>JavaDay 2013</h4>
<p>In the middle of March we had JavaDay, a JugMK organized event, where I had two talks. One was called <a href="http://mitemitreski.github.io/talks/query-dsl.html#/"> QueryDSL - Clean way to have SQL in your java applications</a> and the other with a more unconventional name <a href="http://mitemitreski.github.io/talks/premature.html#/">Premature optimization, is it normal</a> where the various pros and cons of selected optimization were overviewed.</p>
<h4>The book</h4>
<p>
<a href="http://www.amazon.com/gp/product/B00EZ226G0/ref=as_li_qf_sp_asin_il?ie=UTF8&camp=1789&creative=9325&creativeASIN=B00EZ226G0&linkCode=as2&tag=mitemitresk01-20">
<img style="float:left" src="data:image/jpeg;base64,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b28vHR0dDa1fIQTd3d0MDg5y2WWXMTo6ylVXXcV5553H9ddfT39/P1/4whf46U9/itUk8p2wbZ5+6ikADj30UCpxAk+5XOaKK67gP/7jPxr5HEEQNAIU9TyHeg4zRInzdZ3jarXacE3qKxA333wzfX19jdGxvsZb367+0DRuUByEUUphWVZjFG/OJ/E8j0QigVIKz/Ma4fq6y3Dbbbdx2GGH8b73vY9CvtB4cA907JfxNotDH3vssXz961/ntNNO421vexunnXYaEL12H3/8cQBuu+02LrzwQmzbprOzk127djUWzusd7TgO69ev58477+Q973lPY2knWReQJtL9HRwc5Mknn+SUU07hqKOO4uCDD+aee+7hy1/+Mvfffz8AW7Zs4YILLmDjxo0sXbqUTZs28eUvf5kLL7yQf/7nf+aoo45i/fr1LF26lEwqhQ5DRKhJ2QnWPvgQjz68jvPPP5/PfOYzLFq0iM9//vOcccYZtLa2NtI3e3p6+MAHPkBXVxcf/ehHAXjwwQdZt24dABdccAEDAwOcddZZnHrqqdx9992Mjo6STqcpl8u8//3v51e/+hUf//jHWbZsGdVqFdd1OeWUUzj++ONZvnw5p556Klu2bOHJJ59k7dq1HHbYYZxzzjl0d3c3zvnAAw/w0EMPAfDJT36Snp4e3vWud3HQQQdxxx13NJKFnn76ad797nfz2GOP8fd///d09/TgeS5/Ekk+Cwbm6n35mTd3rp47b54eGBjQAwMD+ic/+YlWSmmllNZaa9/39Ve/+lXd2dmply1bpu+//36ttdblcllrrfU3vvEN7TiOvvrqq7XWWr/xjW/UfX19euHChbq9vV1fcMEFWmutb7zxRt3d3a37+/v1scceq7XW+mc/+5lOJBL6nHPO0ePj441zDg0N6TPPPFO3t7frK6+8UmutdT6f11prffvtt+tZs2bp973vfbpcLutqtaqHhoa07/v6C1/4gu7p7taL5s3XCwbm6oVz5+lZPb36uGOO1eseeURrrXUYhlprrdesWaMPPfRQ3d3drVeuXKnvvPNOrbXWnudprbX+5je/qWfNmqX7+vr05z//eV2pVBrte/zxx/XRRx+tW1pa9Nq1a3WhUNB9fX36+OOP11pr/Ytf/EKvXLlSV6tVvWHDBr1z506ttdalUkm///3v17lcTh977LF6/fr1Wmut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" alt="html5 data book">
</a>
I had my first book, which I co-authored with <a href="https://twitter.com/spion">Gorgi Kosev</a> called <a href="http://www.amazon.com/gp/product/B00EZ226G0/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B00EZ226G0&linkCode=as2&tag=mitemitreskic-20">"HTML5 data and services cookbook"</a>, published. The book took a lot of my personal time which basically became non-existent. In any case this was an awesome experience for me and I liked the outcome of the book. This a not going to be some classics programming book like <a href="http://www.amazon.com/gp/product/020161622X/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=020161622X&linkCode=as2&tag=mitemitreskic-20">Pragmatic programmers</a>, <a href="http://www.amazon.com/gp/product/0132350882/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0132350882&linkCode=as2&tag=mitemitreskic-20">Clean code</a> or even like <a href="http://www.amazon.com/gp/product/0596007124/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0596007124&linkCode=as2&tag=mitemitreskic-20">Head First Design patterns</a>, it will not be something of value 10 years from now, but I did not expect it to be when I got involved .</p>
<p>On the other hand, I will not say <a href="http://www.codinghorror.com/blog/2007/10/do-not-buy-this-book.html">"Do Not Buy This Book"</a>, like Jeff Atwood did for his <a href="http://www.amazon.com/gp/product/098028581X/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=098028581X&linkCode=as2&tag=mitemitreskic-20">The ASP.Net 2.0 Anthology: 101 Essential Tips, Tricks & Hacks</a>, but then it is quite possible that I'm not all that self-critical. Our goal was to create a book that would be of a great use to a programmer who has not really seen javascript as a real language and has only changed stuff here and there. To some extend we have achieved that. On the other hand, as my friend <a href="https://twitter.com/andonsikavica">Andon</a> said "you got to be crazy to write a HTML5/Javascript book nowadays".
I went throught the book-writing process for the first time similarly as Jeff Atwood did, and can confirm that it is far from glamorous. My personal perspective on his points and few of my own is the following:</p>
<ul>
<li><p><strong>Writing a book is hard work</strong> - lots of the parts surrounding the book-writing can be hard (there is a joke in here somewhere). It is time consuming and the hardest part is not having immediate results or if you are doing things the right way. I can't agree with Jeff that there is no enjoyment it the process, since if that was the case, I would have given up very soon. However, it is true that you slave away for you publisher for a long period of time, and the additional challenge is that you need to stay fresh for your real day job and girlfriend.</p>
</li>
<li><p><strong>Writing a book does not pay</strong> - this was something I was familiar with from the start and it is true for most of the programming books. The book-contracting involves an advance for the authors that is intended to feed them until the book is published. The main problem here is that they are usually way too low for you to only be doing the writing. Our publisher was PacktPub and its rate is usually about 3000$ for first-time authors (1500$ if they are two). This is similar to Apress, where the initial rate is 5000$. There are various rates between publishers for the advance but what's probably more of an interest are the book rates. Packt gives 16% of the wholesale price of the book, meaning for a book that costs 100$, the wholesale price would be about 50% and the authors rate would be about 5$. There is a more detailed <a href="http://www.charlespetzold.com/blog/2007/10/081247.html">article</a> by Charles Petzold that should give you a better insight. In general, power houses like O'reilly can spend good amount of money in promoting you, and with that your book, but this is not the case with other smaller publishers so you might wanna consider self-publishing. There is also a cool post by John Resig about <a href="http://ejohn.org/blog/programming-book-profits/">Programming Book Profits</a>. On the other hand, <a href="http://pragdave.me/post/70459641113/pragmatic-royalties-2013-edition">Pragmatic Publishing</a> recently came out with interesting numbers, but then again those are most likely the one percenters for programming books.</p>
</li>
<li><p><strong>Cookbooks are restrictive</strong> - my book was a "Programming Cookbook" and added various restriction of what can be written. Each of the <em>"recipes"</em> needs to be an independent seciton with its own subsections, a short intro where you have the freedom to add anything you want, a <em>"Getting ready"</em> section where you have the code setup, a step by step guide on <em>"how to do it"</em> (yet another joke), the explanation on <em>"how it works"</em> and my favorite section "There's more". I have a major dislike for the <em>"how to do it blocks"</em> mostily because at times they felt like large sections of code that would not be a part of an non-cookbook type of book. Additional constrains were added by our publisher since for some reason we had to use .doc/.docx file format for the writing part. We were even disqussing the creation of a tool that generates document with the publisher styles from a reasonable markup(markdown,asciido even latex), but this whole part is a longer story. </p>
</li>
<li><p><strong>Anyone can write a book</strong> - I completely agree with this. There is the ego-filling moment when you show up on Amazon or when you get the print copy in you hands, or even when you get errata( Oh the errata), even if we ignore the financial reasons. I personally don't find the book as some sort of major accomplishments. As Jeff notes, people are impressed by authors, which also to me is kind of crazy. Basically anyone can write a book, I wrote a book surely you can as well. The only thing you need is a desire to write it and it will get published. Even if it is not accepted by a classic publisher, there is Amazon direct publishing, Lean Publishing as well as many other self-publishing options, and those books are not any better or worse than the rest.</p>
</li>
<li><p><strong>Most books will not succeed</strong> - I previously added that anyone can be an author but not many have successful books. As Jeff states, the only real measurments are sales. One can argue that <a href="http://www.amazon.com/gp/product/0345803485/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=93">"50 shades of Gray"</a> was not artistically as valuable as this year's Pulitzer Prize winner and that may or may not be true, but it sure outsold that one. The same goes for programming books, I'm not the biggest fan of <a href="http://www.amazon.com/gp/product/0596007124/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0596007124&linkCode=as2&tag=mitemitreskic-20">Head First Design Patterns</a> if I compare it with most of the other O'reilly books, but that one outsold almost all of programming books, so they must be doing something right.</p>
</li>
</ul>
<p>I won't suggest you not to write a book like Jeff did, I sure did not listen to him so why should you?! Before you start, make sure that such undertaking is what you really are passionate about and consider all the other options. I would now personally prefer blog posts over writing a full book just because you get the immediate feedback. If you are still considering it, read Seth Godin's <a href="http://sethgodin.typepad.com/seths_blog/2006/08/advice_for_auth.html">Advice for authors</a>.</p>
<h4>Java2Days</h4>
<p>As I noted in a previous blog <a href="http://blog.mitemitreski.com/2013/12/java2days-2013-modern-workflows-for.html#.Ur4Hcd-OXXI">post</a> this is an event that happens 5 years in a row and it is the nearest real conference to JugMK's location. These type of events are great for connecting the various smaller communities near Macedonia and Bulgaria as well as creating new opportunities for all attendants. This one had the importance for me since it was a first public talk in front of international audience. I have done several lectures in the past while I was working as SUN/Oracle trainer as well as few internal company events but none of these were really in front of a public audience.</p>
<h4>Java Day#0x02</h4>
<p>This is the event that I'm also very excited about that happened just a week ago. This was probably the best organized event by JugMK so far, mostly due to the involvement of our member <a href="https://twitter.com/hsilomedus">Pance</a> in the event preparations. The event went very smoothly and had great selection of talks. The talks are being added to Pareleys but for better or worse most of them are on Macedonian. This was the 4-th JavaDay in the past 4 years and the second this year which brought great new crowd. My talk was titled "State of the lambda" and was greatly inspired by the finial document for the Java 8 Lambdas. In a sense this is the year where the rebirth of Java is getting started, it is something that was mentioned by <a href="https://twitter.com/Stephan007">Stephan Janssen</a> on the opening of Devoxx and it is very accurate. I do expect 2014 to be a great year for all JVM development. Note that I'm writing JVM and not Java since Java/JVM has become lot more than a language, but more of an ecosystem that is awesome for development.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNzDF-066IkURoNYhJUtRX3Pj6t5OY7dvwG-A_YquMA2cWOUAI4sfOtNNaobaUPCTBLovqTJj0oviqT4dyM5GavQrPba4KrKYe1ohZu7bQ5qViFAulTqGVL0-m4Z9g3LA93gLAhxL0RMA/s1600/origin_4758387047.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNzDF-066IkURoNYhJUtRX3Pj6t5OY7dvwG-A_YquMA2cWOUAI4sfOtNNaobaUPCTBLovqTJj0oviqT4dyM5GavQrPba4KrKYe1ohZu7bQ5qViFAulTqGVL0-m4Z9g3LA93gLAhxL0RMA/s400/origin_4758387047.jpg" /></a></div>
<h3>The goals for 2014</h3>
<p>This would be my short list of goals for next years. Hopefully if I make them public I will make the most effort in fulfilling them:</p>
<ul>
<li><strong>I will make an effort not to write a book</strong> ( how is that for a goal ?). Joke aside, I will make an effort to write 2 blog posts per week. It is not something unreasonable and that would mean at the end of 2014 there should be at least 104 posts.</li>
<li><strong>Personal/Side projects</strong> - I pledge to finish some of my half-done personal projects that never saw the light of day due to various reasons (main one here is procrastination ).</li>
<li><strong>The uncomfortable side</strong> - I will pick a language/technology that I feel uncomfortable with and make a whole project in it. There is some deciding to be done on this,but still I have a pretty good idea.</li>
<li><strong>Get out more</strong> - I think this is something that was not happening for the past 2 years and it is really important in order to have a good work/life balance.</li>
<li><strong>Contribute to open source</strong> - Try to make significant contribution an "important" project, or at least something that I find important. I have submitted few patches in the past and some bugreports here and there but nothing I'm really proud of.</li>
</ul>
<p>All of these should be simple enough and reachable within reasonable amount of time. By announcing them publicly I am adding additional incentive to make them happen. This is in some sense a <a href="http://en.wikipedia.org/wiki/Commitment_device">commitment device</a> something that the authors of <a href="http://www.amazon.com/gp/product/0606324305/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0606324305&linkCode=as2&tag=mitemitresk01-20">freakonomics</a> would define as :</p>
<blockquote>
<p>A means with which to lock yourself into a course of action that you might not otherwise choose but that produces a desired result</p>
</blockquote>
<p>Time will show if this will work. I like to finish the whole story with a quote from Trainspotting</p>
<blockquote>
<p>Choose life. Choose a job. Choose a career. Choose a family. Choose a fucking big television. Choose washing machines, cars, compact disc players and electrical tin openers..... Choose DIY and wondering who the fuck you are on a Sunday morning. Choose sitting on that couch watching mind numbing, spirit crushing game shows, stuffing junk food into your mouth. Choose rotting away at the end of it all, pissing your last in a miserable home, nothing more than an embarrassment to the selfish, fucked-up brats you spawned to replace yourself. Choose your future. Choose life..... But why would I want to do a thing like that?</p>
</blockquote>
<br />
<br />
photo credit: <a href="http://www.flickr.com/photos/gnews/4758387047/">gnews pics</a> via <a href="http://photopin.com">photopin</a> <a href="http://creativecommons.org/licenses/by/2.0/">cc</a>
<br />Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-76980374519063644762013-12-07T20:35:00.001+01:002020-11-09T22:26:03.337+01:00Functional Java Collections<em>This blog post crossposted and originally part of the 2012 edition <a href="http://javaadvent.com/">Java Advent Calendar</a> a lovely initiative from </em><i><a href="http://hype-free.blogspot.com/" target="_blank">Attila-Mihaly Balazs </a>and the Transilvania JUG </i><br />
<br />
There is a lot of functional hype these days so I would give a short overview on what is out there at least when it comes to collections in Java. Personally I like standard <a href="http://java.sun.com/docs/books/tutorial/collections/index.html">collections API</a> but i some cases can be awkward and add additional verboseness. This should not be a problem in latter version of Java 8+. There we would probably worry about not creating callback hell but hey there is no silver bullet for most stuff why should there be one for programming?<br />
<h2>
The Guava Way
</h2>
Guava project is one of Google's core libraries where there are plenty of different core language aspects and problems covered. There are utilities and extensions for everyday usage like : collections, primitives, caching, common annotations, string processing, I/O, Math, Reflections and many others. We will only take a look at the Collections goodies so lets see some of them :
<br />
<code></code>
<br />
<pre class="prettyprint"><code> // list
ImmutableList<String> of =
ImmutableList.of("a", "b", "c", "d");
// Same one for map
ImmutableMap<String, String> map =
ImmutableMap.of("key1", "value1", "key2", "value2");
//list of ints
List<Integer> theList = Ints.asList(1, 2, 3, 4, 522, 5, 6);
</code></pre>
The Guava Collections are compatible with the JDK collections since they mostly extend or implement the standard classes.
There are several cool utilities that are part of the API and have similar names with the ones from <i>java.util.Collections</i>. Basically any programmer who knows the JDK collections should be able to transfer to Guava easily. The ones for <i>List</i> is called <i>Lists</i>, one for <i>Set</i> is Sets, for <i>Map</i> is <i>Maps</i> and so on for the rest. For example:
<code></code>
<br />
<pre class="prettyprint"><code>//create new List
List<someLongName> list = Lists.newArrayList();
//create new LinkedHashMap
Map<someKeyType, SomeValueType> map = Maps.newLinkedHashMap();
//initalize Array List on the spot
List<String> someList = Lists.newArrayList("one", "two", "three");
//set inital size for readability as well as performance
List<Type> exactly100 = Lists.newArrayListWithCapacity(100);
List<Type> approx100 = Lists.newArrayListWithExpectedSize(100);
</code></pre>
<br />
Methods corresponding to a particular interface are grouped in a very intuitive manner. There are also some extremely good ways of building <a href="http://code.google.com/p/guava-libraries/wiki/CachesExplained">cache</a> with various of features :
<br />
<code></code><br />
<pre class="prettyprint"><code> Cache<Integer, Customer> cache = CacheBuilder.newBuilder()
.weakKeys()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<Integer, Customer>() {
@Override
public Customer load(Integer key) throws Exception {
return retreveCustomerForKey(key);
}
});
</code></pre>
<br />
Since Guava is available in most of the maven repositories its very easy to add it to your <a href="http://code.google.com/p/guava-libraries/wiki/UseGuavaInYourBuild"> build </a>
<br />
<h2>
lambdaj
</h2>
The idea behind the project is to manipulate collections in a functional and statically typed way. This is achieved in a way the avoids repetitions of simple tasks we usually do with collections.
Repetition makes programmers to go with copy/pasting and creates makes them create bugs by doing so. Accessing collections without explicit looping provides way of filtering, sorting, extraction, grouping, transforming, invoking a method on each item or sum up the elements or fields of those element in a collections.
Additionally to all these features lambdaj is also a DSL in a way since it adds very cool "sugar" features to the syntax making it more readable in pseudo-english. This is done with static methods so in order to use them we include them directly:
<br />
<code></code><br />
<pre class="prettyprint"><code>import static ch.lambdaj.Lambda.*;
</code></pre>
As it comes to checking and matching lambdaj relies deeply on <a href="https://github.com/hamcrest/JavaHamcrest">Hamcrest</a>matchers. So for example to create a check for an odd integers and then filter a list with that check:
<code></code><br />
<pre class="prettyprint"><code>Matcher<Integer> odd = new Predicate<Integer>() {
public boolean apply(Integer item) {
return item % 2 == 1;
}
};
List<Integer> oddNumbers = filter(odd, asList(1, 2, 3, 4, 5));
</code></pre>
<code>
</code>
and as expected the list will return the list [1,3,5]. Lambdaj take a step further with it's DSL, for example :
<code></code><br />
<pre class="prettyprint"><code>List<Beneficiary> beneficiaries = with(transactions)
.retain(having(on(Transaction.class)
.getQunatity(), lessThan(100)))
.extract(on(Transaction.class).getBeneficiary())
.sort(on(Beneficiary.class).getName());
</code></pre>
<code>
</code>
<br />
<br />
<h2>
Performance costs
</h2>
Although the best way to make your application fast is to have the cleanest code as possible there comes a time when you must optimize.In order to do that there is some info provided by the creators on the memory usage and time. Lambdaj has a performance <a href="http://code.google.com/p/lambdaj/wiki/PerformanceAnalysis"> wiki page</a> with code examples. There are also some test done by other programmers where they <a href="https://github.com/dmalch/lambda-comparison">compare</a> lambdaj with JDK8 for example. There are also some measurements on <a href="http://code.google.com/p/memory-measurer/wiki/ElementCostInDataStructures"> memory </a> usage of Guava. As for performance of Guava most of it's functionality is standard JDK classes builders and utilities so the overhead is minimal. At the end of the day it's up to you to decide how much effect each of these libraries will have on your project and if that is positive. I'm for the idea that almost every project must have Guava on it's classpath.
<br />
<h5>
Related links summary
</h5>
<ul>
<li>Guava <a href="http://code.google.com/p/guava-libraries/">http://code.google.com/p/guava-libraries/</a></li>
<li>lambdaj <a href="http://code.google.com/p/lambdaj/">http://code.google.com/p/lambdaj/</a> </li>
<li>Hamcrest <a href="http://hamcrest.org/">http://hamcrest.org/</a> </li>
<li>Guava Links <a href="http://www.tfnico.com/presentations/google-guava">http://www.tfnico.com/presentations/google-guava</a> </li>
<li>Guava examples <a href="https://github.com/mitemitreski/guava-examples">https://github.com/mitemitreski/guava-examples</a> </li>
<li>Guava presentation <a href="http://blog.mitemitreski.com/2012/07/google-guava-for-cleaner-code.html">http://blog.mitemitreski.com/2012/07/google-guava-for-cleaner-code.html</a></li>
</ul>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-49205659477693943462013-12-03T16:37:00.003+01:002020-11-09T17:49:12.774+01:00Java2Days 2013 : Modern workflows for JavaScript integrationFor the past 4 years we (<a href="http://jug.mk/" target="_blank">JugMK</a>) have visited <a href="http://java2days.com/" target="_blank">Java2days</a> but this year I decided to have talk of my own. Java2days is somewhat local conference in a sense that the attendees are mosty from Bulgaria and some from Macedonia and Seriba, but it is definitely the best Java conference in the area.<br />
<br />
How did I end up with the topic?<br />
<br />
<div>
My last few projects required good integration of JavaScript with Java EE, so I decided to share my previous experience in a talk. The presentation included what's out there and how a good use of Yeoman integrates nicely into Java EE project.</div>
<div>
<br /></div>
<iframe allowfullscreen="" frameborder="0" height="356" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/28846453?rel=0" style="border-width: 1px 1px 0; border: 1px solid #CCC; margin-bottom: 5px;" width="600"> </iframe> <br />
<br />
As for the demo, I went through the basic files of the <a href="https://github.com/yeoman/generator-angular" target="_blank">Angular generator</a> for Yeoman without getting into the specific of the scaffoldings of directives and other Angular specific features.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbErPF-ep_OYlER7JBnZANCzFT5nKaeJ4IX7Eu4nUNlGHTAnXKzqdYDqgl7ICMHwvIS2uz6gpEXS7G2XxCE8XxAOx_W06-KMsL6ywNeQIUNQ8G0gbKTK7pJBgx0XanHQgA7_Z5TM0RW3c/s1600/img1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbErPF-ep_OYlER7JBnZANCzFT5nKaeJ4IX7Eu4nUNlGHTAnXKzqdYDqgl7ICMHwvIS2uz6gpEXS7G2XxCE8XxAOx_W06-KMsL6ywNeQIUNQ8G0gbKTK7pJBgx0XanHQgA7_Z5TM0RW3c/s320/img1.jpg" width="320" /></a></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-nEQ_rsDuuE0eHVv8ZrdVmGNsXFbIPter_Yy-RVba8Boe-y0SKXw310W5rKyVM6an_891uZW2kEalDMbo3bxtJyisQBWlipTbO1lNUl04rhhRjU5SrvNK5k8BpjgBT19JtUA7LsGxt68/s1600/img2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-nEQ_rsDuuE0eHVv8ZrdVmGNsXFbIPter_Yy-RVba8Boe-y0SKXw310W5rKyVM6an_891uZW2kEalDMbo3bxtJyisQBWlipTbO1lNUl04rhhRjU5SrvNK5k8BpjgBT19JtUA7LsGxt68/s320/img2.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Img by <a href="https://twitter.com/hsilomedus" target="_blank">@hsilomedus</a></td></tr>
</tbody></table>
<br />
<br />
<div style="margin-bottom: 5px;">
<b>Links</b><br />
<ul>
<li>Web Jars - Javascript in a JAR <a href="http://webjars.org/">webjars.org</a></li>
<li>Yeoman <a href="http://yeoman.io/">yeoman.io</a></li>
<li>Grunt, task runner <a href="http://gruntjs.com/">gruntjs.com</a></li>
<li>Node package manager NPM <a href="http://npmjs.org/">npmjs.org</a></li>
<li>Karma test <a href="http://karma-runner.github.io/">karma-runner.github.io</a></li>
<li>Shameless promo <a href="http://www.amazon.com/gp/product/B00EZ226G0/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B00EZ226G0&linkCode=as2&tag=mitemitreskic-20" target="_blank">html5 data and services cookbook</a></li>
</ul>
</div>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-16785245623426593802013-11-10T22:42:00.003+01:002020-11-09T22:26:21.303+01:00[Book review] Getting Started with Google GuavaI was contacted a month ago by someone from PacktPub to review a book called <a href="https://amzn.to/2HPfWFk" target="_blank">"Getting Started with Google Guava"</a> by Bill Bejeck(<a href="http://codingjunkie.net/">http://codingjunkie.net/</a>). I'm not so keen on reading one more tech book just for the fun of it, but since it was about Guava I accepted the offer.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://amzn.to/2HPfWFk" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWSbZdg1O4499rSko1WDBRMwz_194zN8-LIgdmI-rhV6TNmyMfO7bBDgCVEPeeqlEQhIcgoe8tEbqOW8_Vgdh5hOTSi1YB39jhnBFgPX0WOC1tK7UhnQaLUwrOk_XxEzgrIL3tb_apY1I/s1600/guava.jpg" /></a></div>
Reading Guava book might come in strange for anyone as it is for me since I've read the docs, few tutorials, some blog posts. On top of that I'm using it regularly each day and I have written a <a href="http://www.javaadvent.com/2012/12/functional-java-collections.html" target="_blank">blogpost</a> and did <a href="http://blog.mitemitreski.com/2012/07/google-guava-for-cleaner-code.html" target="_blank">talk</a> on the subject. But having a more structured way of getting your self introduced and learn new stuff is always a good thing and so is this book.<br />
<br />
First chapter is concerned with introduction to Guava, some history and the reasoning of why it should end up in your build path. Next there are chapters on the basic utilities, Guava's functional aspects and the various collections that are available. There is a separate chapter on Cache that I found it really detailed and one for the useage of EventBus which is basically a cool way to get Publish/Subscribe model out of the box.<br />
<br />
<a href="https://code.google.com/p/guava-libraries/wiki/HashingExplained#BloomFilter" target="_blank">Bloom Filters </a>and the concurrency goodies were something completely new to me and they definitely made the book worth reading. Additionally I found out about the <a href="https://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Tables" target="_blank">Table class</a>, which is something I have completely missed and most definitely needed in the past.<br />
To sum it all up, its a good book and one which is very easy to read, in mine case a plane trip filled with Guava awesomenessMite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-31994985577048028382012-12-16T14:24:00.004+01:002020-11-09T17:49:40.169+01:00Java Advent CalendarOn 14.12.2012 I took part of initiative called <a href="http://www.javaadvent.com/">Java Advent Calendar</a> with a post about
<a href="http://www.javaadvent.com/2012/12/functional-java-collections.html?spref=bl"> Functional Java collections</a>. The idea for the Calendar is very simple, one technical article will be published per day between the 1st and 24th of December. This initiative is done for other languages like <a href="http://www.perladvent.org/2012/">Perl</a> or <a href="http://webadvent.org/2011">PHP</a> and even some frameworks like <a href="http://advent.perldancer.org/2011">Perl Dancer</a>.
You can directly sign up on
<a href="http://feeds.feedburner.com/JavaAdventCalendar">the RSS feed</a>
or follow
<a href="http://feedburner.google.com/fb/a/mailverify?uri=JavaAdventCalendar&loc=en_US">via e-mail</a>.
How can you help? Sharing on the social networks is highly appreciated.
You can also visit the original <a href="http://www.javaadvent.com/2012/11/systemoutprintlnhello-world.html">hello world post</a> or read on Wikipedia about <a href="http://en.wikipedia.org/wiki/Advent_calendar" target="_blank">Advent Calendars</a>.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjarqc8iyhuAgF_p2uQD1k55Zd6j9P1tTEt5CKkBBz2wvXwmQtwtU5mzstXzRAbyoXYiaZ4MLaZyQKsz-ocavehmXeKDZOQjoxdROicls13MDaIET1qFGV1PCO-xJSR6jktiHxe1TxX-Q/s1600/Rathaus_H%25C3%25BCnfeld_Adventskalender.JPG" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjarqc8iyhuAgF_p2uQD1k55Zd6j9P1tTEt5CKkBBz2wvXwmQtwtU5mzstXzRAbyoXYiaZ4MLaZyQKsz-ocavehmXeKDZOQjoxdROicls13MDaIET1qFGV1PCO-xJSR6jktiHxe1TxX-Q/s320/Rathaus_H%25C3%25BCnfeld_Adventskalender.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Image of Advent calendar using the actual windows of the German city of Hünfeld's town hall in Advent <a href="http://en.wikipedia.org/wiki/File:Rathaus_H%C3%BCnfeld_Adventskalender.JPG">© Wikimedia</a> </td></tr>
</tbody></table>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-39928673732222272562012-11-26T10:19:00.001+01:002020-11-09T22:26:34.564+01:00Temporary files and directories in Java 7 and before<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl5iI4Wndb25W_L0Af4SPZfNcaHKD-Mi1D92WNrfCZkYQICFY9Mc6eTxxbS4kzk8lcxsHYE2-Fr3Z-xZY4vNxCRYim3R5nRqa4GQtrJ1ZRjfZUvaH9pJton9ScaDuwbKQtsdGwE77oEmo/s1600/Temporary_plate.svg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl5iI4Wndb25W_L0Af4SPZfNcaHKD-Mi1D92WNrfCZkYQICFY9Mc6eTxxbS4kzk8lcxsHYE2-Fr3Z-xZY4vNxCRYim3R5nRqa4GQtrJ1ZRjfZUvaH9pJton9ScaDuwbKQtsdGwE77oEmo/s1600/Temporary_plate.svg.png" /></a></div>
<br />Sometimes we want to create a temporary file, whether to save some data that gets written by some other application or just to temporary store stuff. Well, usually applications have their own temporary folder where they do this and it gets somehow configured. But why not use the underlying OS specific file like <i>"/tmp/"</i> in Linux so there must be some system property that has this info and there is. The key is <i>"java.io.tmpdir"</i> resulting in <i>"/tmp"</i> in my case or by code:<br />
<pre><code class="java">
String tempDir = System.getProperty("java.io.tmpdir");
</code>
</pre>
We can use <i>tempDir</i> folder as a temporary place to store files, but there are a lot nicer ways to work with files like this even in JDK6 not just in JDK7:<br />
<pre><code>
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class TempFile {
public static void main(String[] args) {
try {
// create a temp file
File tempFile = File.createTempFile("old-file", ".tmp");
tempFile.deleteOnExit();
System.out.println("Temp file : " + tempFile.getAbsolutePath());
// nio style
final Path path = Files.createTempFile("nio-temp", ".tmp");
System.out.println("Temp file : " + path);
//call the same delete on exit
path.toFile().deleteOnExit();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
Files.delete(path);
System.out.println("deleted file at "+path);
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
</code>
</pre>
The JDK 7 way is the use the Files class and use Path 's that can easily enable us way to create and work files and their attributes and permissions. Calling<i> tempFile.deleteOnExit()</i> or path.toFile().deleteOnExit() will enable the files to be deleted automatically after the virtual machine terminates. Files are deleted in the reverse order that they are registered and besides that we need to be careful about what the path is.<br />
Deletion will only happen if JVM is closed under normal condition and not for example using kill -9 (SIGKILL) under Linux. <br /><br />One other interesting option is to do the deletion with a shutdown hook using <i>"Runtime.getRuntime().addShutdownHook(new Thread() {...}"</i> that registers a new virtual-machine shutdown hook. This shutdown hook is simply an initialized thread, but it is not started. The thread will only be executed when the virtual machine begins its shutdown sequence during normal shutdown.<br />
<br />
<b><i>Related Links</i></b><br />
<ul>
<li><a href="https://github.com/mitemitreski/blog-examples/raw/master/basics/src/com/mitemitreski/blog/example/tempfile/TempFile.java" target="_blank">code example on GitHub </a></li>
<li><a href="http://docs.oracle.com/javase/tutorial/essential/io/fileio.html" target="_blank">http://docs.oracle.com/javase/tutorial/essential/io/fileio.html </a></li>
<li><a href="http://docs.oracle.com/javase/tutorial/essential/io/fileio.html" rel="nofollow">Five ways to maximize Java NIO and NIO2</a></li>
<li><a href="http://jcp.org/en/jsr/detail?id=203">JSR 203</a></li>
<li><a href="http://docs.oracle.com/javase/7/docs/api/java/nio/file/package-summary.html">NIO JavaDoc</a></li>
</ul>
Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-19544075955194719352012-10-09T17:26:00.003+02:002020-11-09T22:26:42.410+01:00Input this - input that, HTML5 new input typesWe are used to inputting types like "submit", "radio" or "hidden" but these days there are more components that are so common that are part of almost every web framework out there no matter if it is in Java, Ruby, Python or any other language. I'll give a short overview of what is being added in HTML5. The current state of them is that well... they sort of work, basically not all of the features are supported in all the modern browsers or IE.<br />
Opera seems to support most of them and they have some good initial look there.<br />
<br />
<h4>
Date selection related.</h4>
Many times you need to create or integrate some control that will be a date-time picker, I've done this way too often and I'm sure that you also have. But why should we do something like this, this should be part of HTML and we should just style it with CSS. HTML5 makes this very simple with the date input types.<br />
<pre><code>
<input type="datetime" />
<input type="datetime-local" />
<input type="date" />
<input type="week" />
<input type="time" /></code></pre>
<pre></pre>
<i>Live example:</i><br />
<input type="datetime" /><br />
<input type="datetime-local" /><br />
<input type="date" /><br />
<input type="week" /><br />
<input type="time" /><br />
<h4>
</h4>
<h4>
Emails, Phone and URL</h4>
<table class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPF6ht5ZaBjEjETOJhbj7Nbi1LgyxLKnBJ6W7LBKZYDTUu7undyE8iN1cSOh_3OBrN6BJwsC8TM81RDuhX0MpFJV9_H-NytyNfsAmCd-3EEnhVuvLn8pblvKen3cB_S_H91iaS943HYJ0/s1600/email.png" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img alt="" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPF6ht5ZaBjEjETOJhbj7Nbi1LgyxLKnBJ6W7LBKZYDTUu7undyE8iN1cSOh_3OBrN6BJwsC8TM81RDuhX0MpFJV9_H-NytyNfsAmCd-3EEnhVuvLn8pblvKen3cB_S_H91iaS943HYJ0/s320/email.png" height="83" title="email validation" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Email validation example on Opera 12</td></tr>
</tbody></table>
<table class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYaaBaMx09RKPE3K4e7CRcni4Oa6mZe23FCkv3fE9YY5FvvzI-mq1xEG4G0wtXx7qowzIICBz-F-oPbqPKwNWKUWfCiEwQ-ARLL9WdRjIO-5e_adBIyawz0cjK_BbHNXjCL9Uy3F6dBPo/s1600/web.jpg" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYaaBaMx09RKPE3K4e7CRcni4Oa6mZe23FCkv3fE9YY5FvvzI-mq1xEG4G0wtXx7qowzIICBz-F-oPbqPKwNWKUWfCiEwQ-ARLL9WdRjIO-5e_adBIyawz0cjK_BbHNXjCL9Uy3F6dBPo/s1600/web.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Input type email on iOS</td></tr>
</tbody></table>
Why would you need input types for this, well first thing is validation that otherwise you would need to do with JavaScript on the client side.<br />
You could also style with CSS using input type specific selectors like <i>input[type=radio]. </i>Best thing about the input types by far is that they are semantically correct so mobile phones open input type specific view on the keyboard.<br />
<pre> <code>
<form>
<input name="email" type="email" pattern="[^ @]*@[^ @]*" value="" />
<input id="url" type="url" />
<input id="phone" type="tel" />
<input type="submit" />
</form>
</code></pre>
<i>Live example:</i><br />
<table class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTn8n9YAzE22RngKqbIm0IcMpUajLzTUb7p5NeMNEPs4EwqI_kBZ98Ms1D4VE450l1uUlyc4aTHt0_A2hJaMlC0DCz8cHbM-JCBQfY1DI3iPEAQUHNpGEypy1tO08F8IVKDP6tAPOor5U/s1600/number.jpg" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTn8n9YAzE22RngKqbIm0IcMpUajLzTUb7p5NeMNEPs4EwqI_kBZ98Ms1D4VE450l1uUlyc4aTHt0_A2hJaMlC0DCz8cHbM-JCBQfY1DI3iPEAQUHNpGEypy1tO08F8IVKDP6tAPOor5U/s1600/number.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Input type phone on iOS</td></tr>
</tbody></table>
<br />
<form>
<input id="email" type="email" /><br />
<input id="url" type="url" /><br />
<input id="phone" type="tel" /><br /></form>
<br />
<br />
<h4>
</h4>
<h4>
</h4>
<h4>
Color</h4>
Input type that results in color picker.<br />
<pre><code>
<input type="color" /></code></pre>
<input type="color" /><br />
<br />
<br />
<br />
Isn't this what you always wanted? ... at least when it comes down to html input.<br />
<br />
<b><i>TL;DR version </i></b><br />
<blockquote>
NEW HTML5 input types, awesome!!! see <a href="http://mitemitreski.com/demo/html5/input.html">demo</a></blockquote>
<br />
<br />
<b><i>Related Links</i></b><br />
<br />
Demos - <a href="http://mitemitreski.com/demo/html5/input.html">http://mitemitreski.com/demo/html5/input.html</a><br />
W3 input element spec - <a href="http://www.w3.org/TR/2011/WD-html5-20110525/the-input-element.html">http://www.w3.org/TR/2011/WD-html5-20110525/the-input-element.html</a><br />
Support test - <a href="http://www.quirksmode.org/html5/tests/inputs_dates.html">http://www.quirksmode.org/html5/tests/inputs_dates.html</a><br />
Mozzila developers article - <a href="https://developer.mozilla.org/en-US/docs/HTML/Element/Input">https://developer.mozilla.org/en-US/docs/HTML/Element/Input</a><br />
Web Platform page - <a href="http://docs.webplatform.org/wiki/html/elements/input/type/search">http://docs.webplatform.org/wiki/html/elements/input/type/search </a>Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-38022338362489917272012-07-15T01:13:00.001+02:002020-11-09T22:26:50.591+01:00Mustaches in the world of JavaMustache is templating system with implementation in many languages including Java and JavaScript . The templates are also supported by various web frameworks and client side JS libraries.<br />
<br />
Mustache has simple idea of "logic-less" system because it lacks any explicit control statements, like <i>if</i>, <i>else or goto </i>and<i> </i>also it does not have <i>for</i> statement however looping and conditional calculation can be achieved using custom tags that work with lists and lambdas.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2Q12zQfImuniK5zkZZlF5r5iXtZ1EL0EIz1v9SJKp30bYRN2oIfJIeWXgCXgXV1d2zfyPJdVQ9Q9GhxTsiUwNVYgP7f9LpvEGrYUx_FvPAM1cdvUBYko96Vlh3dc7L9zXz5uJ6O_sBBY/s1600/mustache.jpe" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><br /></a>
<a href="http://www.amazon.com/gp/product/B002R7XO3Y/ref=as_li_ss_tl?ie=UTF8&tag=mitemitreskic-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=B002R7XO3Y" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCtL7QuSGVeiP0kCf3JcojME6hqRbriykDBP0tBkQVwpaE1Bug3krm0XZuQsQVXV4uzwez8jycG5JMY0jvb4H-UGVabyou1PcJLk5M5PN78bZkDuWAFWtGSaR_QTYnUndXUt7WKmA3vMA/s320/mustache.jpg" height="262" width="320" /></a><br />
The name unfortunately has less to do with Tom Selleck but more with the heavy use of curly braces that look like mustache. The similarity is more than comparable.<br />
<br />
<br />
Mustache has implementation for most of the widely used languages like: Java, Javascript, Ruby,Net and many <a href="http://mustache.github.com/">more</a>.<br />
<br />
<br />
<br />
<br />
<br />
<h3>
The client side template's in JavaScript</h3>
Let say that you have some REST service and you have created a book view object that has an additional function that appends amazon associates id to the book url:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQsLfnnTobU3xAS9C-wwLKYpe28rpYeaXkN4UVIg-zniQq1_-lNGJ8CdL4gr_892-nOy36q0SWmDgrxaqA7G52JqVVMsWJet1mcX6jRusKYmusYoEeN6eZBuCqA9w9mWXJTqzHAFlcybY/s1600/mustache.jpe" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a>
<br />
<pre><code class="javascript">
var book = {
id : 12,
title : "A Game of Thrones",
url : "http://www.amazon.com/gp/product/0553573403/",
amazonId : "myAwesomeness",
associateUrl : function() {
return this.url + '?tag=' + this.amazonId;
},
author : {
name : 'George R. R. Martin',
imdbUrl : 'http://www.imdb.com/name/nm0552333/',
wikiUrl : 'https://en.wikipedia.org/wiki/George_R._R._Martin'
},
haveInStock : true,
similarBooks : [{
id : 13,
title : "Decision Points"
}, {
id : 13,
title : "Spoken from the Heart"
}],
comments : []
};
</code></pre>
<br />
<br />
The standard way of rendering data without using templates would be create an output variable and just append everything inside and at the end just place the data where it should be.<br />
<pre><code class="javascript">
jQuery(document).ready(function() {
var out = '<div class="book-box"><h3>' + book.title +
'</h3><span> is awesome book get it on <a href="' +
book.associateUrl() + '">Amazon</a></span></div>';
jQuery('#content-jquery').html(out);
});
</code>
</pre>
This is fairly simple but if you for example want to change the <i>span</i> element with div it takes a little bit of time to figure where it should be closed and often you can miss if the element should be in single quotes or double quotes. The bigger issue here is that the content is peaces of strings that need to be easy to styled via CSS and JavaScript. As the code gets bigger this becomes unmanageable and changes to anything become slower especially if you add on top of this jQuery's manipulation functions like <i>appendTo</i>() or <i>prependTo(). </i>This direct use of <i>out+= </i>type of creating the content reminds me a lot of HttpServlet style of using print writer and doing <i>out.print()</i> and for the same reason why this was almost abandoned we should not do this in JavaScript. <br />
To simplify work we can add template engine like Mustache that is one of many client side tempting engines. So how does a template in mustache looks like, well for the example above with the book it would look like :<br />
<br />
<pre><code class="html">
<script id="book-template" type="text/x-mustache-template">
<div class="book-box">
<h3>{{title}}</h3>
<span> is awesome book get it on
<a href="{{associateUrl}}">Amazon</a>
</span>
</div>
</code>
</pre>
So this template can be placed anywhere on the page and then selected and rendered when you need it:<br />
<pre><code class="javascript">
jQuery(document).ready(function() {
var template = jQuery('#book-template').html();
var renderedData = Mustache.render(template, book);
jQuery('#content-mustache').html(renderedData);
});
</code>
</pre>
The render method accepts the content of the <i>template</i> and the view object <i>book</i>, what is great here is that the template looks almost the same as html thus make it easy to style, change and maintain. <br />
Also you can use section like : <i>{{#conditon}} code or data here{{/condition}}</i> where if it evaluates to true, the section is rendered,
otherwise the whole block is ignored. <br />
If the conditions returns nonempty list this can be iterated using the same construct. <br />
Inverted condition is done using <i>{^conditon}} code or data here{{/condition}}. </i><br />
Dot notation can be used to access subelements (not in every implementation), for example if you wanted to render the authors imdb page from the previous example it would be like <i>{{author.imdbUrl}}.</i>There are structures called <a href="https://github.com/janl/mustache.js/">partials</a> that can be used<i> </i>if we need render time inclusion of partial elements, also if needed some of the standard behavior of Mustache JS can be overridden. <br />
You can get the example from <a href="https://github.com/mitemitreski/blog-examples/tree/master/mustache-js">https://github.com/mitemitreski/blog-examples/tree/master/mustache-js</a> or play around with the following jsfiddle<br />
<h4>
</h4>
<h3>
<iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/mitemitreski/LqtKX/2/embedded/" style="height: 650px; width: 100%;"></iframe> Server side rendering Mustache in Spring MVC</h3>
There is an implementation of Mustache templates for Java called <a href="http://mustache.java/">Mustache.java</a> and another one called <a href="https://github.com/samskivert/jmustache">JMustache </a>. As far as usage in web frameworks is needed there are few articles out there about using Mustache in Java web applications based on <a href="http://java.dzone.com/articles/using-mustachejava-templates">Struts</a> for example but I went with the Spring MVC option since I found it more interesting for my use.<br />
For the example I used the <a href="https://github.com/sps/mustache-spring-view/"><i>mustache-spring-view</i></a> that is fairly simple to add using maven: <br />
<pre> <code class="xml">
<dependency>
<groupId>com.github.sps.mustache</groupId>
<artifactId>mustache-spring-view</artifactId>
<version>1.0</version>
</dependency>
</code>
</pre>
This will automatically retrieve jMustache :<br />
<i><br /> +- com.github.sps.mustache:mustache-spring-view:jar:1.0:compile<br /> \- com.samskivert:jmustache:jar:1.2:compile</i><br />
<br />
<br />
The next part is including the view in the servlet context and adding the appropriate paths:<br />
<br />
<pre><code class="xml">
<beans:bean id="viewResolver"
class="org.springframework.web.servlet.view.mustache.MustacheViewResolver">
<!-- FIXME reload every time-->
<beans:property name="cache" value="false" />
<!-- The default view path is below -->
<beans:property name="prefix" value="/WEB-INF/views/" />
<!-- The default suffix path is below -->
<beans:property name="suffix" value=".mustache" />
<beans:property name="templateLoader">
<beans:bean
class="org.springframework.web.servlet.view.mustache.MustacheTemplateLoader" />
</beans:property>
</beans:bean>
</code>
</pre>
As you can see the config is extremely simple you just need to add the path where the templates will be stored the suffix that the templates will end in, the actual template loader and if the templates should be cached. It is very good during development to set this property to true since that way you will get instant update on the changes in your templates.<br />
The controller will be very simple one since this is just a small proof of concept:<br />
<pre> <code class="java">
/**
* Hello Mustache.
*/
@Controller
public class HomeController {
private static final Logger logger =
LoggerFactory.getLogger(HomeController.class);
/**
* Simple controller that
* redirects to home and adds map and date objects.
*/
@RequestMapping(value = "/", method = GET)
public String home(Locale locale, Model model) {
Date date = new Date();
DateFormat dateFormat =
DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.LONG, locale);
Properties properties = System.getProperties();
Map<String, String> map =
new HashMap<String, String>((Map) properties);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate);
model.addAttribute("props", map.entrySet());
return "home";
}
}
</code>
</pre>
The controller just fills the serer system properties and the current time add passes the model to towards the template. Acorrding to the previous configuration the template name is <i>home.mustache</i> and it is located in <i>/WEB-INF/views/. </i><br />
Template is as simple as it gets, the idea here was just to illustrate how java maps can be iterated.<br />
<pre> <code>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset=utf-8>
<title>Hello Mustache</title>
</head>
<body>
<div id="container">
<p>Current server time is {{serverTime}}</p>
<p>All the current system properties</p>
<ul>
{{#props}}
<li>{{key}} = {{value}} </li>
{{/props}}
</ul>
</div>
</body>
</html>
</code>
</pre>
So how does it work? Well if we take <i>serverTime</i> it can be java property, key or a method which makes it very simple and readable. The full example can be retrieved from my <a href="https://github.com/mitemitreski/blog-examples/blob/master/mustache-java/mustache-spring-mvc/src/main/webapp/WEB-INF/views/home.mustache">github page.</a><br />
It's just the regular maven clean package and run, it's tested on tomcat 6 with Java 1.6 but it simple enough to work anywhere. While I can't yet say that I have used the servers side rendering in a production environment they most definitely look promising. There are plugins for <a href="https://gist.github.com/323622">vim</a>, <a href="https://gist.github.com/323619">emacs</a> and <a href="https://gist.github.com/323624">textmate</a> but there is no plugin for eclipse. On eclipse you can do a workaround Eclipse->Preferences->General->Content_Types add the *.mustache to be recognized as html, at least you will get the html syntax highlighting.<br />
The cool thing with Mustache is that you can very easily switch whether you gonna use server side rendering on client side additionally it makes it very hard to add unnecessary logic in the templates that makes development simpler.<br />
Don't forget your app is only hot if it has awesome mustaches.<br />
<br />
<pre><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQsLfnnTobU3xAS9C-wwLKYpe28rpYeaXkN4UVIg-zniQq1_-lNGJ8CdL4gr_892-nOy36q0SWmDgrxaqA7G52JqVVMsWJet1mcX6jRusKYmusYoEeN6eZBuCqA9w9mWXJTqzHAFlcybY/s1600/mustache.jpe" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img alt="mustache js" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQsLfnnTobU3xAS9C-wwLKYpe28rpYeaXkN4UVIg-zniQq1_-lNGJ8CdL4gr_892-nOy36q0SWmDgrxaqA7G52JqVVMsWJet1mcX6jRusKYmusYoEeN6eZBuCqA9w9mWXJTqzHAFlcybY/s1600/mustache.jpe" title="" /></a></pre>
<b>Update</b><br />
I got few questions regarding the use of partials with the Spring resolver. So here is the clarification. When using partials you need to use the full relative name:<br />
<pre><code>
{{> /WEB-INF/views/partial.mustache}}
</code>
</pre>
The updated example can be found on<br />
<a href="https://github.com/mitemitreski/blog-examples/tree/master/mustache-java/mustache-spring-mvc">https://github.com/mitemitreski/blog-examples/tree/master/mustache-java/mustache-spring-mvc</a> that demonstrates the use of partials.<br />
<br />
There is a pull request that improves the syntax a little bit on<br />
<a href="https://github.com/sps/mustache-spring-view/pull/3">https://github.com/sps/mustache-spring-view/pull/3</a> but it is not yet accepted.<br />
<h4>
Other links</h4>
<ul>
<li><a href="https://github.com/janl/mustache.js/">https://github.com/janl/mustache.js/ </a></li>
<li><a href="http://mustache.github.com/">http://mustache.github.com</a>/ </li>
<li><a href="https://github.com/mustache/spec">https://github.com/mustache/spec</a></li>
<li><a href="http://www.javarants.com/2010/05/03/the-ideal-web-application-templating-system/">http://www.javarants.com/2010/05/03/the-ideal-web-application-templating-system/</a></li>
<li><a href="https://github.com/samskivert/jmustache">https://github.com/samskivert/jmustache</a></li>
<li><a href="http://java.dzone.com/articles/using-mustachejava-templates">http://java.dzone.com/articles/using-mustachejava-templates</a></li>
<li><a href="https://github.com/sps/mustache-spring-view/">https://github.com/sps/mustache-spring-view/</a></li>
<li><a href="http://stackoverflow.com/questions/4410544/is-there-a-mustache-template-syntax-highlighter-or-plugin-for-eclipse">http://stackoverflow.com/questions/4410544/is-there-a-mustache-template-syntax-highlighter-or-plugin-for-eclipse</a></li>
<li><a href="https://groups.google.com/forum/?fromgroups#%21forum/mustachejava">https://groups.google.com/forum/?fromgroups#!forum/mustachejava</a></li>
</ul>
<ul>
</ul>
<br />
<br />Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.comtag:blogger.com,1999:blog-3233503126001905087.post-20030886479926168232012-07-06T01:12:00.001+02:002022-10-23T01:02:08.388+02:00Google Guava for cleaner code<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilNuAqixAiWe_i7GcQ_aeThsyiL1sdQA30HxNTk6Iyv8urOSy6nsuWvSziMzlvUnu2IfETWuv8p9Z7hLLnRPDsHaYrIF6-gQKt0A1gtgbKX-isTKlSHwTp0XzcA-U3OxW8VMD2CXst4Xg/s1600/guava.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilNuAqixAiWe_i7GcQ_aeThsyiL1sdQA30HxNTk6Iyv8urOSy6nsuWvSziMzlvUnu2IfETWuv8p9Z7hLLnRPDsHaYrIF6-gQKt0A1gtgbKX-isTKlSHwTp0XzcA-U3OxW8VMD2CXst4Xg/s200/guava.jpg" width="193" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Guava </td></tr>
</tbody></table>
Some time ago I did a short talk on Google Guava for our local <a href="http://www.jug.mk/">JUG.</a> It was a basic intro into Guava and how it makes stuff simpler, better and cleaner. <br />
<br />
It is true that there is an <a href="http://code.google.com/p/guava-libraries/wiki/ApacheCommonCollectionsEquivalents">overlap</a> with Apache commons but Guava is build with expectation that there is a Function and a Predicate class as well as various builders which makes it really cool and simple for many use cases.<br />
The talked covered most of the <i>com.google.common.base.*</i> classes and basic use of functions in collection and Google collections and few other features that are part of Guava and I find them very useful.<br />
Source code of the examples can be found on <a href="https://github.com/mitemitreski/guava-examples">github</a> and here is the actual presentation: <br />
<iframe src="//www.slideshare.net/slideshow/embed_code/key/BLUOsRykENMuB7" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/mitemitreski1/google-guava-for-cleaner-code" title="Google Guava for cleaner code" target="_blank">Google Guava for cleaner code</a> </strong> from <strong><a href="//www.slideshare.net/mitemitreski1" target="_blank">Mite Mitreski</a></strong> </div>
<br />
Note one last recommendation that is not just mine but also part of Guava's wiki :<br />
<blockquote>
Excessive use of Guava's functional programming idioms can lead to verbose, confusing, unreadable, and inefficient code. These are by far the most easily (and most commonly) abused parts of Guava, and when you go to preposterous lengths to make your code "a one-liner," the Guava team weeps.
</blockquote>
<br />
<br />
<br />
<i>Related links </i><br />
<ul>
<li><a href="http://code.google.com/p/guava-libraries/">http://code.google.com/p/guava-libraries/</a></li>
<li><a href="http://code.google.com/p/guava-libraries/wiki/UseGuavaInYourBuild">http://code.google.com/p/guava-libraries/wiki/UseGuavaInYourBuild</a> </li>
<li><a href="https://github.com/mitemitreski/guava-examples">https://github.com/mitemitreski/guava-examples </a></li>
<li><a href="http://stackoverflow.com/questions/tagged/guava">http://stackoverflow.com/questions/tagged/guava</a></li>
<li><a href="http://www.tfnico.com/presentations/google-guava#TOC-Presentation">http://www.tfnico.com/presentations/google-guava#TOC-Presentation</a></li>
<li><a href="http://gdg-krakow.github.com/google-io-ext-2012-guava/">http://gdg-krakow.github.com/google-io-ext-2012-guava/</a></li>
</ul>
<br />Mite Mitreskihttp://www.blogger.com/profile/16383703873667320161noreply@blogger.com