Jekyll2021-12-27T09:51:19+00:00https://www.dovydasvenckus.dev//Dovydas Venckus blogThoughts on java, linux and other geeky topics.Dovydas VenckusMJML config for FreeMarker tags2020-08-18T19:30:00+00:002020-08-18T19:30:00+00:00https://www.dovydasvenckus.dev/software-engineering/2020/08/18/mjml-config-for-freemarker<p>Recently I was working on a project which used <code class="language-plaintext highlighter-rouge">MJML</code> for building responsive HTML emails and <code class="language-plaintext highlighter-rouge">FreeMarker</code> as a template engine.
I have faced some hurdles while integrating <code class="language-plaintext highlighter-rouge">MJML</code> with FreeMarker tags.</p>
<h2 id="problem-with-default-config">Problem with default config</h2>
<p>I have started experiencing issues after enabling CSS inlining.
MJML for CSS inlining uses <a href="https://github.com/Automattic/juice">Juice</a> library.
Turns out that <code class="language-plaintext highlighter-rouge">Juice</code> by default doesn’t play nicely with FreeMarker tags.</p>
<p><code class="language-plaintext highlighter-rouge">Juice</code> by default lower cases all HTML tag attributes, so <code class="language-plaintext highlighter-rouge"><#if task.dateCreated?has_content></code> is turned into
<code class="language-plaintext highlighter-rouge"><#if task.datecreated?has_content></code></p>
<h2 id="solution">Solution</h2>
<p>To make MJML play nicely with FreeMarker you must configure <code class="language-plaintext highlighter-rouge">Juice</code>
to skip processing FreeMarker tags.</p>
<p>You can follow steps below or take a look into sample project
on <a href="https://github.com/blog-dovydasvenckus/mjml-freemarker-config">GitHub</a>.</p>
<h3 id="create-mjmlconfig-config-file">Create <code class="language-plaintext highlighter-rouge">.mjmlconfig</code> config file</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">{</span>
<span class="s2">"packages"</span>: <span class="o">[]</span>,
<span class="s2">"options"</span>: <span class="o">{</span>
<span class="s2">"juicePreserveTags"</span>: <span class="o">{</span>
<span class="s2">"freeMarkerStartTag"</span>: <span class="o">{</span>
<span class="s2">"start"</span>: <span class="s2">"<#"</span>,
<span class="s2">"end"</span>: <span class="s2">">"</span>
<span class="o">}</span>,
<span class="s2">"freeMarkerEndTag"</span>: <span class="o">{</span>
<span class="s2">"start"</span>: <span class="s2">"</#"</span>,
<span class="s2">"end"</span>: <span class="s2">">"</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="enable-config-file">Enable config file</h3>
<p>While running <code class="language-plaintext highlighter-rouge">mjml</code> command add –config.useMjmlConfigOptions=true flag, to pull config from <code class="language-plaintext highlighter-rouge">.mjmlconfig</code> file.</p>
<p>E.g:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mjml --config.useMjmlConfigOptions=true -r src/templates/*.mjml -o build/templates/
</code></pre></div></div>
<h2 id="conclusion">Conclusion</h2>
<p>The solution is pretty simple and straight forward, but it is not well documented.</p>
<p>I hope this article was useful. If you have any questions or suggestions feel free to leave a comment.</p>Dovydas VenckusRecently I was working on a project which used MJML for building responsive HTML emails and FreeMarker as a template engine. I have faced some hurdles while integrating MJML with FreeMarker tags.One PSU two fried CPU’s2020-07-12T20:30:00+00:002020-07-12T20:30:00+00:00https://www.dovydasvenckus.dev/hardware/2020/07/12/one-psu-two-fried-cpus<p>My recent PC upgrade ended up with couple fried CPU’s.</p>
<p>Recently I have tried to upgrade my ITX build cooling. I have compact Lian-Li PC-Q01B case,
which uses PSU as air exhaust and for intake you can install one 120mm or 140mm fan.</p>
<p>Along with the fan I have decided to upgrade my trusty FSP Aurum 400W PSU.
Mainly because it was non-modular and unused cables would have blocked airflow from the bottom fan.
To increase airflow I have decided to go with SFX modular power supply.</p>
<p>I was choosing between beQuiet SFX-L 500 and Fractal Design ION SFX 500W.
I have chosen Fractal Design PSU, because I have read that this particular model is manufactured by Sea Sonic.
So I expected a high-quality power supply, but it turned out to be defective.</p>
<p>Bellow, I will outline the timeline and weather Fractal Design support will compensate fried parts.</p>
<h2 id="event-sequence">Event sequence</h2>
<h3 id="friday-may-22">Friday, May 22</h3>
<p>Connected PSU to my current PC with Intel I7-6700K CPU. Computer fans were spinning but, I didn’t receive any video output.
I have tried to boot system without a video card, tried booting with a single stick of ram in different ram slots.
But still could not boot the system.</p>
<p>I have pulled out an old motherboard with Pentium G4400 processor.
I have placed motherboard on the cardboard box and hooked up PSU, to make sure that nothing is shorted.
And the same situation fans were spinning, but no video output.</p>
<p>After that, I hooked my old PSU to both systems, and none of them were working, so I knew that some components were dead.</p>
<h3 id="monday-may-25">Monday, May 25</h3>
<p>Picked up used Pentium G4400 for 10EUR.
Tried out both motherboards with new G4400 and my old PSU both systems was booting just fine.
I can conclude that the Fractal Design power supply has fried both CPU’s.
Both of the CPU’s are out of warranty period, so I can’t RMA them.</p>
<h3 id="wednesday-may-27">Wednesday, May 27</h3>
<p>Brought PSU to the local retailer for inspection.
They also asked to bring not working motherboard and CPU for inspection.
I brought both CPU’s with my motherboard.</p>
<h3 id="friday-may-29">Friday, May 29</h3>
<p>A local retailer repair center has called me and informed me that PSU is defective. They also confirmed that both of the CPU’s were dead.</p>
<h3 id="friday-july-10">Friday, July 10</h3>
<p>Received a full refund for PSU.</p>
<h3 id="sunday-july-12">Sunday, July 12</h3>
<p>Opened ticket on Fractal Design support system regarding damaged parts due to faulty product</p>
<h3 id="tuesday-july-21">Tuesday, July 21</h3>
<p>Received first response from Fractal support. They informed me that they need to inspect PSU,
to confirm that parts were fried by PSU.</p>
<p>I have asked them to inspect it by serial number because it was already returned to Fractals
repair center by my local retailer.</p>
<h3 id="friday-september-11">Friday, September 11</h3>
<p>Received reply after almost two months of waiting. I expected a delay due to the ongoing pandemic, but not two months.</p>
<p>Because they could not be certain that CPU fried my CPU’s, they didn’t refund me the cost of the CPU’s.
Instead, they offered to choose any product from their lineup. And I have chosen ITX case with the worst
cooling potential a.k.a. Fractal Design Era Itx. But I’m a sucker for small cases, especially with wooden panels.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I was excited about this upgrade, but it turned out as a really frustrating one.
I have spent a significant amount of time trying to trace and isolate not working part.
And for almost past two month’s I have lived with crappy CPU, with noticeably lower multitasking performance.
And on top of that, I have lost perfectly functioning parts that I bought with my hard-earned money.</p>
<p>But on the bright side, I have a new case and a reason to upgrade to AMD Ryzen 5000 series CPU.</p>
<p><strong>But I’ll keep updating this blog post with my experience with their support.</strong></p>Dovydas VenckusMy recent PC upgrade ended up with couple fried CPU’s.NPM ci vs install2020-04-04T16:30:00+00:002020-04-04T16:30:00+00:00https://www.dovydasvenckus.dev/javascript/2020/04/04/npm-install-vs-npm-ci<p>While working with multiple people on the same project,
I have always been annoyed by the way <code class="language-plaintext highlighter-rouge">npm install</code> works.
Running <code class="language-plaintext highlighter-rouge">npm install</code> after checking out code always caused
different <code class="language-plaintext highlighter-rouge">package-lock.json</code> than <code class="language-plaintext highlighter-rouge">package-lock.json</code> checked in source control.</p>
<p>Also, there is a bigger problem when <code class="language-plaintext highlighter-rouge">npm install</code> is used on CI server.
CI server might update <code class="language-plaintext highlighter-rouge">package-lock.json</code> and install newer
versions of packages than intended. It might lead to bugs that
were not present on the developer’s machine.</p>
<p><code class="language-plaintext highlighter-rouge">npm install</code> had <code class="language-plaintext highlighter-rouge">--no-save</code> flag which allowed to install packages without
modifying <code class="language-plaintext highlighter-rouge">package-lock.json</code>. So there was a workaround, but it was
not that convenient. Simple human factor error could cause, CI server to build a broken app.</p>
<h2 id="npm-ci-to-the-rescue">NPM ci to the rescue</h2>
<p>In the spring of 2018 <strong>Node 6.0</strong> was released, which contained new <code class="language-plaintext highlighter-rouge">npm ci</code> command.</p>
<p>Main differences from <code class="language-plaintext highlighter-rouge">npm install</code>:</p>
<ul>
<li>Removes <code class="language-plaintext highlighter-rouge">node_modules</code> directory and installs new <code class="language-plaintext highlighter-rouge">node_modules</code> using <code class="language-plaintext highlighter-rouge">package-lock.json</code>.</li>
<li>Never updates <code class="language-plaintext highlighter-rouge">package.json</code> or <code class="language-plaintext highlighter-rouge">package-lock.json</code>. If packages in <code class="language-plaintext highlighter-rouge">package.json</code> do not match with packages in <code class="language-plaintext highlighter-rouge">package-lock.json</code> it will throw error.</li>
<li>Can’t install new packages.</li>
</ul>
<p>While working locally if someone updated <code class="language-plaintext highlighter-rouge">packages.json</code> I can pull code and run <code class="language-plaintext highlighter-rouge">npm ci</code>,
without generating different <code class="language-plaintext highlighter-rouge">package-lock.json</code>.
<code class="language-plaintext highlighter-rouge">npm ci</code> does not replace <code class="language-plaintext highlighter-rouge">npm install</code>, because it can’t update <code class="language-plaintext highlighter-rouge">package-lock.json</code>.
I use <code class="language-plaintext highlighter-rouge">npm install</code> to sync <code class="language-plaintext highlighter-rouge">package-lock.json</code> with changed <code class="language-plaintext highlighter-rouge">packages.json</code>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I’m glad that Node team included <code class="language-plaintext highlighter-rouge">npm ci</code> command.
It’s quite useful locally and when running node builds on automated build servers.
It’s a pity that I found this command not that long ago.</p>Dovydas VenckusWhile working with multiple people on the same project, I have always been annoyed by the way npm install works. Running npm install after checking out code always caused different package-lock.json than package-lock.json checked in source control.Moved to .dev top level domain2019-12-07T12:30:00+00:002019-12-07T12:30:00+00:00https://www.dovydasvenckus.dev/blog/2019/12/07/new-domain-dev<p>I have moved my blog to <a href="https://www.dovydasvenckus.dev">dovydasvenckus.dev</a> domain,
because I think it is more suitable for this blog.</p>
<p>All requests from the old address will be redirected to the current blog.
So it shouldn’t cause any inconveniences.</p>Dovydas VenckusI have moved my blog to dovydasvenckus.dev domain, because I think it is more suitable for this blog.Mocking Spring beans with Spock2019-05-05T16:00:00+00:002019-05-05T16:00:00+00:00https://www.dovydasvenckus.dev/java/2019/05/05/mocking-spring-beans-with-spock<p>I love Spock testing framework, it has much more elegant syntax that JUnit.
Also, I think it has a gentle learning curve compared to JUnit.
Not so long ago to Mock or Stub Spring context beans was a pain in the butt.
But Spock 1.2 version introduced an easier way to Mock and Stub spring beans.</p>
<p>In my examples I’ll be using Spring Boot 2.1.</p>
<h2 id="old-way">Old way</h2>
<p>In the old days to Mock or Stub Spring bean, we had to create separate Spring configuration which
created our beans using <code class="language-plaintext highlighter-rouge">DetachedMockFactory</code>.</p>
<p><strong>Example of old way:</strong></p>
<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@SpringBootTest</span>
<span class="nd">@Import</span><span class="o">(</span><span class="n">TestConfig</span><span class="o">)</span>
<span class="kd">class</span> <span class="nc">AccountServiceIntegrationSpec</span> <span class="kd">extends</span> <span class="n">Specification</span> <span class="o">{</span>
<span class="nd">@Autowired</span>
<span class="n">AccountRepository</span> <span class="n">accountRepository</span>
<span class="nd">@Autowired</span>
<span class="n">AccountService</span> <span class="n">accountService</span>
<span class="kt">def</span> <span class="s1">'should save new account'</span><span class="o">()</span> <span class="o">{</span>
<span class="nl">given:</span>
<span class="n">AccountDTO</span> <span class="n">account</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AccountDTO</span><span class="o">(</span><span class="nl">name:</span> <span class="s2">"Income"</span><span class="o">,</span> <span class="nl">type:</span> <span class="n">INCOME</span><span class="o">)</span>
<span class="n">Account</span> <span class="n">accountWithId</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Account</span><span class="o">(</span><span class="nl">id:</span> <span class="mi">5</span><span class="o">,</span> <span class="nl">name:</span> <span class="s2">"Income"</span><span class="o">,</span> <span class="nl">type:</span> <span class="n">INCOME</span><span class="o">)</span>
<span class="n">accountRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">_</span> <span class="k">as</span> <span class="n">Account</span><span class="o">)</span> <span class="o">>></span> <span class="n">accountWithId</span>
<span class="nl">when:</span>
<span class="n">AccountDTO</span> <span class="n">result</span> <span class="o">=</span> <span class="n">accountService</span><span class="o">.</span><span class="na">createAccount</span><span class="o">(</span><span class="n">account</span><span class="o">)</span>
<span class="nl">then:</span>
<span class="n">with</span><span class="o">(</span><span class="n">result</span><span class="o">)</span> <span class="o">{</span>
<span class="n">id</span> <span class="o">==</span> <span class="mi">5</span>
<span class="n">name</span> <span class="o">==</span> <span class="s1">'Income'</span>
<span class="n">type</span> <span class="o">==</span> <span class="n">INCOME</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">static</span> <span class="kd">class</span> <span class="nc">TestConfig</span> <span class="o">{</span>
<span class="n">DetachedMockFactory</span> <span class="n">mockFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">DetachedMockFactory</span><span class="o">()</span>
<span class="nd">@Bean</span>
<span class="nd">@Primary</span>
<span class="n">AccountRepository</span> <span class="nf">accountRepositoryStub</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">mockFactory</span><span class="o">.</span><span class="na">Stub</span><span class="o">(</span><span class="n">AccountRepository</span><span class="o">)</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>As you can see it contains quite a lot boilerplate code to Stub single bean. And it was error prone, you had to remember to <code class="language-plaintext highlighter-rouge">@Import</code> your <code class="language-plaintext highlighter-rouge">TestConfig</code> class.</p>
<h2 id="post-spock-12-way">Post Spock 1.2 way</h2>
<p>Thankfully Spock 1.2 improved bean Mocking and Stubbing quite a lot and it became a trivial operation.</p>
<p><strong>Example:</strong></p>
<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@SpringBootTest</span>
<span class="kd">class</span> <span class="nc">AccountServiceIntegrationSpec</span> <span class="kd">extends</span> <span class="n">Specification</span> <span class="o">{</span>
<span class="nd">@SpringBean</span>
<span class="n">AccountRepository</span> <span class="n">accountRepository</span> <span class="o">=</span> <span class="n">Stub</span><span class="o">()</span>
<span class="nd">@Autowired</span>
<span class="n">AccountService</span> <span class="n">accountService</span>
<span class="kt">def</span> <span class="s1">'should save new account'</span><span class="o">()</span> <span class="o">{</span>
<span class="nl">given:</span>
<span class="n">AccountDTO</span> <span class="n">account</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AccountDTO</span><span class="o">(</span><span class="nl">name:</span> <span class="s2">"Income"</span><span class="o">,</span> <span class="nl">type:</span> <span class="n">INCOME</span><span class="o">)</span>
<span class="n">Account</span> <span class="n">accountWithId</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Account</span><span class="o">(</span><span class="nl">id:</span> <span class="mi">5</span><span class="o">,</span> <span class="nl">name:</span> <span class="s2">"Income"</span><span class="o">,</span> <span class="nl">type:</span> <span class="n">INCOME</span><span class="o">)</span>
<span class="n">accountRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">_</span> <span class="k">as</span> <span class="n">Account</span><span class="o">)</span> <span class="o">>></span> <span class="n">accountWithId</span>
<span class="nl">when:</span>
<span class="n">AccountDTO</span> <span class="n">result</span> <span class="o">=</span> <span class="n">accountService</span><span class="o">.</span><span class="na">createAccount</span><span class="o">(</span><span class="n">account</span><span class="o">)</span>
<span class="nl">then:</span>
<span class="n">with</span><span class="o">(</span><span class="n">result</span><span class="o">)</span> <span class="o">{</span>
<span class="n">id</span> <span class="o">==</span> <span class="mi">5</span>
<span class="n">name</span> <span class="o">==</span> <span class="s1">'Income'</span>
<span class="n">type</span> <span class="o">==</span> <span class="n">INCOME</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Everything is done with only two lines. It differs from regular Stubbing only by single <code class="language-plaintext highlighter-rouge">@SpringBean</code> annotation.</p>
<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nd">@SpringBean</span>
<span class="n">AccountRepository</span> <span class="n">accountRepository</span> <span class="o">=</span> <span class="n">Stub</span><span class="o">()</span>
</code></pre></div></div>
<p>To use this <code class="language-plaintext highlighter-rouge">@SpringBean</code> annotation you must include <a href="https://mvnrepository.com/artifact/org.spockframework/spock-spring"><code class="language-plaintext highlighter-rouge">org.spockframework:spock-spring</code></a> dependency in your <code class="language-plaintext highlighter-rouge">classpath</code>.</p>
<p>Also, there is <code class="language-plaintext highlighter-rouge">@SpringSpy</code> annotation for creating spies, but generally I’m against spying, because usage of Spies, in my opinion, is bad code smell.</p>
<h2 id="summary">Summary</h2>
<p>Spock 1.2 version solved an old issue with Mocking and Stubbing Spring beans. You can read more about the latest Spock releases on their <a href="https://github.com/spockframework/spock/blob/master/docs/release_notes.adoc">GitHub page</a>.</p>
<p>If you have any questions feel free to leave a comment below.</p>
<p>Happy testing :)</p>Dovydas VenckusI love Spock testing framework, it has much more elegant syntax that JUnit. Also, I think it has a gentle learning curve compared to JUnit. Not so long ago to Mock or Stub Spring context beans was a pain in the butt. But Spock 1.2 version introduced an easier way to Mock and Stub spring beans.Raspberry PI 2 Kodi Youtube 60 FPS video lag2019-05-04T20:30:00+00:002019-05-04T20:30:00+00:00https://www.dovydasvenckus.dev/kodi/2019/05/04/kodi-raspberry2-youtube-60fps-lag<p>I was experiencing video lag with <strong>60 FPS</strong> <strong>Youtube</strong> videos on <strong>Raspberry PI 2</strong> running <strong>LibreELEC 9.0</strong>. 60 FPS videos were choppy, video lagged behind audio and was completely unwatchable.</p>
<p>After playing around with overclocking settings I have found out that stock RPI2 GPU clock is just a little bit underpowered for 60FPS video. Small overclock should fix this issue.</p>
<p>By default RPI2 GPU clock speed is 250 MHz. By boosting GPU clock to 300 MHz I have solved Youtube 60 FPS video lag.</p>
<p>The overclocking procedure may be a little different depending on your Raspberry PI OS distribution. Only location of <code class="language-plaintext highlighter-rouge">config.txt</code> file might be different, but otherwise fix should be the same.</p>
<p>In my case I’m using LibreELEC:</p>
<ol>
<li>
<p>SSH into your LibreELEC box.</p>
</li>
<li>
<p>Mount boot partition as Read-Write mode:</p>
<p><code class="language-plaintext highlighter-rouge">mount -o remount,rw /flash</code></p>
</li>
<li>
<p>Edit <code class="language-plaintext highlighter-rouge">/flash/config.txt</code> with vi or nano. E.g. <code class="language-plaintext highlighter-rouge">nano /flash/config.txt</code></p>
<p>Find <code class="language-plaintext highlighter-rouge">force_turbo=0</code> and set it to <code class="language-plaintext highlighter-rouge">1</code>. Setting it to <code class="language-plaintext highlighter-rouge">1</code> will disable dynamic CPU and GPU frequency scaling. With GPU overclock and dynamic scaling I have experienced the same lag.</p>
<p>Add line <code class="language-plaintext highlighter-rouge">gpu_freq=300</code> to overclock your GPU.</p>
<p>Your <code class="language-plaintext highlighter-rouge">/flash/config.txt</code> should look like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ...
force_turbo=1
gpu_freq=300
...
</code></pre></div> </div>
</li>
<li>
<p>Remount boot partition as Read only:</p>
<p><code class="language-plaintext highlighter-rouge">mount -o remount,ro /flash</code></p>
</li>
<li>
<p>Reboot your system</p>
</li>
</ol>
<p>Because overclocking is small it should not require overvolting. In case you’re doing more serious overclock you might need to play around with <code class="language-plaintext highlighter-rouge">over_voltage</code> option in <code class="language-plaintext highlighter-rouge">config.txt</code> file. <strong>Overvolt at your own risk, because might lead to hardware failure</strong>. Read more about overclocking in official RPI <a href="https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md">documentation</a></p>
<p>That’s it Youtube 60 FPS video problem should be solved, by small overclock. You can pat yourself on the back, crack open your favorite drink and enjoy fluid 60 FPS Youtube videos.</p>
<p>As always if you have any questions or suggestion, feel free to comment below.</p>Dovydas VenckusI was experiencing video lag with 60 FPS Youtube videos on Raspberry PI 2 running LibreELEC 9.0. 60 FPS videos were choppy, video lagged behind audio and was completely unwatchable.Kodi Youtube plugin capped at 720p video2019-03-26T20:35:00+00:002019-03-26T20:35:00+00:00https://www.dovydasvenckus.dev/kodi/2019/03/26/kodi-youtbube-not-playing-1080-videos<p>Lately I have been playing around with Kodi on Rasberry Pi 2.</p>
<p>And I have noticed that all of Youtube videos seem pixelated on my 1080p monitor.
After poking around I have found out, that videos are being played at 720p resolution.
<img src="/assets/images/2019-03-26-kodi-youtube-720p/before.png" /></p>
<p>After digging around online, I have found a solution for this problem.</p>
<h3 id="solution">Solution</h3>
<p>In this article I’ll be using <code class="language-plaintext highlighter-rouge">Kodi 18.0</code></p>
<ol>
<li>
<p>Install <code class="language-plaintext highlighter-rouge">InputStream Adaptive addon</code></p>
</li>
<li>
<p>Open Youtube <code class="language-plaintext highlighter-rouge">Add-on</code> settings. (To open sidebar you can press left arrow button, when in Youtube addon)
<img src="/assets/images/2019-03-26-kodi-youtube-720p/youtube-settings-menu.png" /></p>
</li>
<li>
<p>Navigate to MPEG-DASH and enable <code class="language-plaintext highlighter-rouge">Use MPEG-DASH</code> toggle
<img src="/assets/images/2019-03-26-kodi-youtube-720p/input-stream-config.png" /></p>
</li>
<li>
<p>Then go into <code class="language-plaintext highlighter-rouge">Configure InputStream Adaptive</code> and set <code class="language-plaintext highlighter-rouge">Min.Bandwidth (Bit/s)</code> to arbritary big value such as <code class="language-plaintext highlighter-rouge">10000000</code>.
<img src="/assets/images/2019-03-26-kodi-youtube-720p/min-bandwidth.png" /></p>
</li>
<li>
<p>Save changes and restart your device.</p>
</li>
</ol>
<p>After these steps videos should be playing at 1080 or higher resolution.
<img src="/assets/images/2019-03-26-kodi-youtube-720p/after.png" /></p>
<p>As always if you have any questions or suggestion, feel free to comment below.</p>Dovydas VenckusLately I have been playing around with Kodi on Rasberry Pi 2.Fix Firefox unreadable dark input fields on GNOME2018-08-20T20:00:00+00:002018-08-20T20:00:00+00:00https://www.dovydasvenckus.dev/linux/2018/08/20/fix-firefox-dark-input-fields-on-gnome<p><strong>This issue seems to be solved in Firefox 67 version:</strong> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1527048">1527048</a></p>
<p>When using Firefox on a computer with dark GTK theme, Firefox renders input fields using a dark theme.
In some cases, input in fields are unreadable, because field is dark and the text is black.</p>
<p>Most of the pages work fine, because they have CSS themed form fields, which override the default GTK theme.</p>
<h3 id="before">Before:</h3>
<p><img src="/assets/images/2018-08-20-2018-08-20-fix-firefox-dark-input-fields-on-gnome/firefox-form-bad.png" /></p>
<p><br /><br /></p>
<p><img src="/assets/images/2018-08-20-2018-08-20-fix-firefox-dark-input-fields-on-gnome/firefox-form-bad-selected.png" /></p>
<h3 id="after">After:</h3>
<p><img src="/assets/images/2018-08-20-2018-08-20-fix-firefox-dark-input-fields-on-gnome/firefox-fixed.png" /></p>
<h2 id="solution">Solution</h2>
<p>For the last couple of years, I have used a browser plugin to fix field rendering.
But lately, there was a rise in browser plugins which were sold to unethical companies,
which modified plugins to spy on user data or inject custom ads.</p>
<p>For some time I have felt uneasy, because of a rise of such threats.
Recently I have stumbled upon a way how to solve this issue without browser plugin.</p>
<ol>
<li>In Firefox URL bar enter about:config.</li>
<li>Create new String value with name <code class="language-plaintext highlighter-rouge">widget.content.gtk-theme-override</code> (Right click > new > String)</li>
<li>Set value to <code class="language-plaintext highlighter-rouge">Adwaita:light</code> (if your distribution does not use GNOME desktop, you should use a name of light GTK theme which is installed on your PC)</li>
<li>Restart browser</li>
</ol>
<p>Enjoy better browsing experience. I hope this post was helpful.</p>
<p>As always feel free to ask questions in the comment section.</p>Dovydas VenckusThis issue seems to be solved in Firefox 67 version: 1527048Being lazy in Java with orElseGet2017-12-30T20:59:59+00:002017-12-30T20:59:59+00:00https://www.dovydasvenckus.dev/java/2017/12/30/being-lazy-with-orElseGet<p><a href="https://docs.oracle.com/javase/9/docs/api/java/util/Optional.html">Optionals</a>
are really cool Java 8 feature. But it works differently than I thought.
So I’ll show how I have shot my own leg when working with <code class="language-plaintext highlighter-rouge">orElse</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">Client</span> <span class="n">client</span> <span class="o">=</span> <span class="n">findClientInDatabase</span><span class="o">()</span>
<span class="o">.</span><span class="na">orElse</span><span class="o">(</span><span class="n">createAndSaveNewClient</span><span class="o">());</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="nc">Optional</span><span class="o"><</span><span class="nc">Client</span><span class="o">></span> <span class="nf">findClientInDatabase</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Searching for client in database"</span><span class="o">);</span>
<span class="k">return</span> <span class="nc">Optional</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="k">new</span> <span class="nc">Client</span><span class="o">());</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="nc">Client</span> <span class="nf">createAndSaveNewClient</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Creating new client"</span><span class="o">);</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Client</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This code should find the client or it should create new client <strong>only if a client does not exist</strong>.</p>
<p>Output:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Searching for client in database
Creating new client
</code></pre></div></div>
<p>As you can see it works differently, then I have expected.
<code class="language-plaintext highlighter-rouge">orElse</code> clause is always evaluated and the result is calculated.</p>
<h2 id="orelseget-to-the-rescue">orElseGet to the rescue</h2>
<p><code class="language-plaintext highlighter-rouge">orElseGet</code> takes supplier function instead of value. And this supplier function
is executed lazily only when Optional value is <code class="language-plaintext highlighter-rouge">empty</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">Client</span> <span class="n">client</span> <span class="o">=</span> <span class="n">findClientInDatabase</span><span class="o">()</span>
<span class="o">.</span><span class="na">orElseGet</span><span class="o">(()</span> <span class="o">-></span> <span class="n">createAndSaveNewClient</span><span class="o">());</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="nc">Optional</span><span class="o"><</span><span class="nc">Client</span><span class="o">></span> <span class="nf">findClientInDatabase</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Searching for client in database"</span><span class="o">);</span>
<span class="k">return</span> <span class="nc">Optional</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="k">new</span> <span class="nc">Client</span><span class="o">());</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="nc">Client</span> <span class="nf">createAndSaveNewClient</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Creating new client"</span><span class="o">);</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Client</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Searching for client in database
</code></pre></div></div>
<h2 id="conclusion">Conclusion</h2>
<p>It is really easy to introduce bug because of <code class="language-plaintext highlighter-rouge">orElse</code> value is always calculated.
This example was taken from a real-world situation. I have almost merged code which
persisted a new entity to the database, even when an entry with the same name has already existed.
Thankfully integration tests have caught it.</p>
<p>Use <code class="language-plaintext highlighter-rouge">orElse</code> mindfully, I would recommend using <code class="language-plaintext highlighter-rouge">orElse</code> only when value is
constant or when <code class="language-plaintext highlighter-rouge">orElse</code> clause won’t have side effects. <code class="language-plaintext highlighter-rouge">orElseGet</code> solves
this issue by loading values lazily.</p>Dovydas VenckusOptionals are really cool Java 8 feature. But it works differently than I thought. So I’ll show how I have shot my own leg when working with orElse.In-depth look at Java try-with-resource2017-12-27T20:45:00+00:002017-12-27T20:45:00+00:00https://www.dovydasvenckus.dev/java/2017/12/27/java-try-with-resource<h2 id="resource-handling">Resource handling</h2>
<p>Before Java 7 working with IO resource (files, JDBC) was tedious, you had
to close the resource manually. Most of these operations with resources can throw
exceptions. Whether the exception was thrown or try block completed without exception
resource should be closed.</p>
<h3 id="pre-java-7-example">Pre Java 7 example:</h3>
<p>Before Java 7 resource closing was mostly done using <a href="https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html">finally</a>.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
<span class="nc">BufferedWriter</span> <span class="n">writer</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedWriter</span><span class="o">(</span><span class="k">new</span> <span class="nc">FileWriter</span><span class="o">(</span><span class="s">"test.txt"</span><span class="o">));</span>
<span class="k">try</span> <span class="o">{</span>
<span class="n">writer</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="s">"My test text"</span><span class="o">);</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">ioException</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// Handle exception</span>
<span class="o">}</span> <span class="k">finally</span> <span class="o">{</span>
<span class="n">writer</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<h3 id="post-java-7-example">Post Java 7 example:</h3>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="k">try</span> <span class="o">(</span><span class="nc">BufferedWriter</span> <span class="n">writer</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedWriter</span><span class="o">(</span><span class="k">new</span> <span class="nc">FileWriter</span><span class="o">(</span><span class="s">"test.txt"</span><span class="o">)))</span> <span class="o">{</span>
<span class="n">writer</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="s">"My test text"</span><span class="o">);</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">ioException</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Handling exception"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>As you can see Java 7 sample is a lot shorter, it lacks finally clause.</p>
<p>In Java 7 resource closing can be delegated to the resource. For this to work
you must initialize resource after <strong>try</strong> clause, in parenthesis. Regardless
if an exception was thrown or try block completed without exception, close method is called.</p>
<h2 id="implementing-your-own-auto-closable-resource">Implementing your own auto closable resource</h2>
<p>At first, I thought that this feature was really cool.
My second thought was “What kind of sorcery is this”. Under the hood, it is really simple,
resource must implement <a href="https://docs.oracle.com/javase/9/docs/api/java/lang/AutoCloseable.html">AutoCloseable</a> interface.
This interface has only single method <code class="language-plaintext highlighter-rouge">void close() throws Exception</code>.</p>
<p><strong>MyFirstAutoCloseableResource.java</strong>:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.dovydasvenckus.resource</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyFirstAutoCloseableResource</span> <span class="kd">implements</span> <span class="nc">AutoCloseable</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">doSomething</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">getClassName</span><span class="o">()</span> <span class="o">+</span> <span class="s">": doing stuff"</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">close</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">getClassName</span><span class="o">()</span> <span class="o">+</span> <span class="s">": closing resource"</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="nf">getClassName</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">this</span><span class="o">.</span><span class="na">getClass</span><span class="o">().</span><span class="na">getSimpleName</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p><strong>Main.java</strong>:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.dovydasvenckus.resource</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="k">try</span> <span class="o">(</span><span class="nc">MyFirstAutoCloseableResource</span> <span class="n">first</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MyFirstAutoCloseableResource</span><span class="o">())</span> <span class="o">{</span>
<span class="n">first</span><span class="o">.</span><span class="na">doSomething</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">catch</span> <span class="o">(</span><span class="nc">Exception</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Handling exception"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>Executing this code should print:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MyFirstAutoCloseableResource: doing stuff
MyFirstAutoCloseableResource: closing resource
</code></pre></div></div>
<p>To demonstrate execution order when an exception occurs I have updated <strong>doSomething</strong> method.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">doSomething</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">getClass</span><span class="o">().</span><span class="na">getSimpleName</span><span class="o">()</span> <span class="o">+</span> <span class="s">": doing stuff"</span><span class="o">);</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="s">"Some exception"</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MyFirstAutoCloseableResource: doing stuff
MyFirstAutoCloseableResource: closing resource
Handling exception
</code></pre></div></div>
<p>As you can see resource was closed before handling the exception.</p>
<p><strong>Tip!</strong> While implementing close method you should specify a more specific type
of Exception. Also, you can specify RuntimeException, this makes <strong>catch</strong> block
optional.</p>
<h2 id="exception-propagation-differences">Exception propagation differences</h2>
<h3 id="finally-resource-closing">Finally resource closing</h3>
<p>When using old style of resource closing <strong>catch block</strong> exceptions are swallowed,
when the exception occurs in <strong>finally</strong> block and only exception from finally is thrown.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="k">try</span> <span class="o">{</span>
<span class="n">methodThatThrowsException</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">catch</span> <span class="o">(</span><span class="nc">RuntimeException</span> <span class="n">exception</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">exception</span><span class="o">);</span>
<span class="o">}</span>
<span class="k">return</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">methodThatThrowsException</span><span class="o">()</span> <span class="o">{</span>
<span class="k">try</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Throwing exception in try block"</span><span class="o">);</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="s">"Try block exception."</span><span class="o">);</span>
<span class="o">}</span> <span class="k">finally</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Throwing exception in finally block"</span><span class="o">);</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="s">"Finally block exception"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p><strong>Output</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Throwing exception in try block
Throwing exception in finally block
java.lang.RuntimeException: Finally block exception
</code></pre></div></div>
<h3 id="try-with-resource">try-with-resource</h3>
<p><strong>FirstAutoCloseableResource.java</strong></p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.dovydasvenckus.resource</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">FirstAutoCloseableResource</span> <span class="kd">implements</span> <span class="nc">AutoCloseable</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">doSomething</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Throwing exception from doSomething()"</span><span class="o">);</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="s">"DoSomething() exception"</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">close</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">RuntimeException</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Throwing exception from close()"</span><span class="o">);</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="s">"close() exception"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p><strong>Main.java</strong></p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.dovydasvenckus.resource</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="k">try</span> <span class="o">(</span><span class="nc">FirstAutoCloseableResource</span> <span class="n">first</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FirstAutoCloseableResource</span><span class="o">())</span> <span class="o">{</span>
<span class="n">first</span><span class="o">.</span><span class="na">doSomething</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">catch</span> <span class="o">(</span><span class="nc">RuntimeException</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ex</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p><strong>Output</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Throwing exception from doSomething()
Throwing exception from close()
java.lang.RuntimeException: DoSomething() exception
</code></pre></div></div>
<p>In this case exception from action was propagated instead of close method exception.
Using try-with-resource you can retrieve exception from close() method by
calling <strong>getSuppressed()</strong> on doSomething() exception.</p>
<h2 id="multiple-resources">Multiple resources</h2>
<p>You can define multiple resources in try statement, Java will handle closing for you.</p>
<p><strong>FirstAutoCloseableResource.java</strong>:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.dovydasvenckus.resource</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">FirstAutoCloseableResource</span> <span class="kd">implements</span> <span class="nc">AutoCloseable</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">doSomething</span><span class="o">()</span> <span class="o">{</span>
<span class="n">printWithClassName</span><span class="o">(</span><span class="s">"Executing doSomething()"</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">close</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">RuntimeException</span> <span class="o">{</span>
<span class="n">printWithClassName</span><span class="o">(</span><span class="s">"Closing resource"</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kt">void</span> <span class="nf">printWithClassName</span><span class="o">(</span><span class="nc">String</span> <span class="n">text</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">getClass</span><span class="o">().</span><span class="na">getSimpleName</span><span class="o">()</span> <span class="o">+</span> <span class="s">": "</span> <span class="o">+</span> <span class="n">text</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p><strong>SecondAutoCloseableResource.java</strong>:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.dovydasvenckus</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SecondAutoCloseableResource</span> <span class="kd">extends</span> <span class="nc">FirstAutoCloseableResource</span> <span class="o">{</span>
<span class="o">}</span></code></pre></figure>
<p><strong>MultipleResources.java</strong>:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.dovydasvenckus.resource</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MultipleResources</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="k">try</span> <span class="o">(</span>
<span class="nc">FirstAutoCloseableResource</span> <span class="n">resource1</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FirstAutoCloseableResource</span><span class="o">();</span>
<span class="nc">SecondAutoCloseableResource</span> <span class="n">resource2</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SecondAutoCloseableResource</span><span class="o">()</span>
<span class="o">)</span> <span class="o">{</span>
<span class="n">resource1</span><span class="o">.</span><span class="na">doSomething</span><span class="o">();</span>
<span class="n">resource2</span><span class="o">.</span><span class="na">doSomething</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p><strong>Output</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>FirstAutoCloseableResource: Executing doSomething()
SecondAutoCloseableResource: Executing doSomething()
SecondAutoCloseableResource: Closing resource
FirstAutoCloseableResource: Closing resource
</code></pre></div></div>
<p>Also, you should keep in mind that Java closes resources in backward declaration order.
It will start closing resources from last to first.</p>
<h2 id="java-9-additions">Java 9 additions</h2>
<p>Before Java 9 you could not initialize <strong>AutoCloseable</strong> resource outside try statement.
Java 9 allows us to define auto closable resources outside try scope.</p>
<p><strong>ResourceOutsideTry.java</strong>:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.dovydasvenckus.resource</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ResourceOutsideTry</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">FirstAutoCloseableResource</span> <span class="n">resource</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FirstAutoCloseableResource</span><span class="o">();</span>
<span class="k">try</span> <span class="o">(</span><span class="n">resource</span><span class="o">)</span> <span class="o">{</span>
<span class="n">resource</span><span class="o">.</span><span class="na">doSomething</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>This might be useful in cases when the resource was passed to function or using dependency
injection. But this has one downside, after cleanup you can still access the resource
and invoke methods on it, this could lead to undesirable behavior.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Try-with-resource reduces boilerplate code and helps to avoid human error in case
we forget to close resource.
I hope you learned something from this long-winded blog post about this simple feature.</p>
<p>If you have any questions feel free to leave a comment.</p>Dovydas VenckusResource handling Before Java 7 working with IO resource (files, JDBC) was tedious, you had to close the resource manually. Most of these operations with resources can throw exceptions. Whether the exception was thrown or try block completed without exception resource should be closed.Java 9 features2017-10-08T20:45:00+00:002017-10-08T20:45:00+00:00https://www.dovydasvenckus.dev/java/2017/10/08/java-9-features<p>Java 9 is a major release, which brings highly anticipated modularization.</p>
<p>I’m late to Java 9 feature release party. But I’ll try to list all features that
have captured my attention.</p>
<h3 id="modularization-project-jigsaw">Modularization (Project Jigsaw)</h3>
<p>Most notable feature in this release is Java module system a.k.a “Jigsaw”.</p>
<p>Module system should solve two problems: encapsulation and dependency declaration.</p>
<p>Before Java 9 all public classes loaded from external Jars were accessible in
the project. Because of this reason, it is easy to accidentally expose API’s that
are meant to be used privately. The new module system addresses it by defining exposed
packages in <code class="language-plaintext highlighter-rouge">module-info.java</code> file.</p>
<p>New module system lets to describe dependencies in <code class="language-plaintext highlighter-rouge">module-info.java</code> file.</p>
<p><strong>budget module-info.java</strong>:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">module</span> <span class="n">com</span><span class="o">.</span><span class="na">dovydasvenckus</span><span class="o">.</span><span class="na">budget</span> <span class="o">{</span>
<span class="n">exports</span> <span class="n">com</span><span class="o">.</span><span class="na">dovydasvenckus</span><span class="o">.</span><span class="na">budget</span><span class="o">;</span>
<span class="n">requires</span> <span class="n">com</span><span class="o">.</span><span class="na">dovydasvenckus</span><span class="o">.</span><span class="na">ledger</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<p><strong>ledger module-info.java</strong>:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">module</span> <span class="n">com</span><span class="o">.</span><span class="na">dovydasvenckus</span><span class="o">.</span><span class="na">ledger</span> <span class="o">{</span>
<span class="n">exports</span> <span class="n">com</span><span class="o">.</span><span class="na">dovydasvenckus</span><span class="o">.</span><span class="na">ledger</span>
<span class="o">}</span>
</code></pre></div></div>
<p>In this example, we have defined budgeting module that exposes only classes from
<code class="language-plaintext highlighter-rouge">com.dovydasvenckus.budget</code> package. Exposed package children are not exposed,
for example, classes in <code class="language-plaintext highlighter-rouge">com.dovydasvenckus.budget.helper</code> package won’t be exposed
to modules that import it.</p>
<p>In this example, I have also defined dependency our budget module depends on ledger
module. Ledger module exposes only classes in <code class="language-plaintext highlighter-rouge">com.dovydasvenckus.ledger</code> package.</p>
<p>Also, JDK was modularized with this release, using <strong>jlink</strong> tool you can create
minimal JRE, that will be deployed with your application. If your application
does not require java.sql module you can make JRE that won’t include it.
It makes sense to deploy lightweight JRE on embedded devices or when we are using
microservices that do not require full JDK.
More on it <a href="http://openjdk.java.net/projects/jigsaw/quick-start#linker">Openjdk docs</a>.</p>
<p>This topic is too wide to describe in this blog post, so I highly recommend
to visit official documentation <a href="http://openjdk.java.net/projects/jigsaw/quick-start">OpenJDK Jigsaw quick start</a>.</p>
<h3 id="http-2-client">HTTP 2 client</h3>
<p>Major browsers supported HTTP/2 for a long time, finally Java has caught up and
introduced HTTP/2 client. This new client also supports WebSockets.</p>
<p>This module is released in incubation state. You can use incubating modules now, but
they will be officially released in a future release.
In JDK10 it should be moved from <code class="language-plaintext highlighter-rouge">jdk.incubator.httpclient</code> to <code class="language-plaintext highlighter-rouge">java.httpclient</code> module.
Also, JDK10 might introduce breaking changes.</p>
<h3 id="java-shell-jshell">Java shell (Jshell)</h3>
<p>Finally, Java has introduced REPL(Read Evaluate Print Loop) shell that allows running
Java commands interactively. Sometimes it is really useful to test code snippet,
for this purpose I have used GroovyConsole. But GroovyConsole is not perfect because
it uses Groovy language which is a superset of Java.</p>
<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">jshell</span><span class="o">></span> <span class="n">String</span> <span class="n">hello</span> <span class="o">=</span> <span class="s2">"Hello World"</span>
<span class="n">hello</span> <span class="o">==></span> <span class="s2">"Hello World"</span>
<span class="n">jshell</span><span class="o">></span> <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">hello</span><span class="o">)</span>
<span class="n">Hello</span> <span class="n">World</span>
</code></pre></div></div>
<p>As you can see commands does not require a semicolon to execute them.
Also, shell supports <strong>Tab</strong> autocomplete, enjoy it :).</p>
<p>Also, I had hope that shell would allow executing commands from a Java file. But it
does not support this feature. In my opinion, it would be nice to be able to write
Java script files and execute them using single command.
So for Java scripting, I’ll stick with Nashorn or Groovy.</p>
<h3 id="javadoc-search">JavaDoc search</h3>
<p><img src="/assets/images/2017-10-08-java-9-features/java-doc-search.png" /></p>
<p>This improvement is small but convenient. Now Java docs support auto completable
search. Before this feature, it was painfully slow to find something in Java API
documentation because you had to navigate using mouse and you had to know
in which package class resides. Whenever I was searching for class
I have always googled because it was a faster way to navigate to class.</p>
<h3 id="stream-improvements">Stream improvements</h3>
<p>One of my favorite features of Java 8 was Streams. It changed the way many people write
code that deals with collections. Code written with streams is compact and easily
readable.</p>
<p>In Java 9 streams got even better.
Stream has 4 new methods:</p>
<ul>
<li><strong>dropWhile</strong> discards first elements of the stream until condicion is met.</li>
<li><strong>takeWhile</strong> process items until condition is met.</li>
<li><strong>iterate</strong> lets write direct replacment for loops.
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Stream</span><span class="o">.</span><span class="na">iterate</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="n">i</span> <span class="o">-></span> <span class="n">i</span> <span class="o"><</span> <span class="mi">100</span><span class="o">,</span> <span class="n">i</span> <span class="o">-></span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="o">)</span>
<span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">);</span>
</code></pre></div> </div>
</li>
<li><strong>OfNullable</strong> Lets create stream without checking if element is null.
When element is non null it returns stream with single element, else it returns
empty Stream.</li>
</ul>
<h3 id="easier-creation-of-immutable-collections">Easier creation of immutable Collections</h3>
<p>Java 9 introduced static methods for different collections. Now it is easier to
create <strong>immutable</strong> lists, sets, maps.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">List</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">fruits</span> <span class="o">=</span> <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Apple"</span><span class="o">,</span> <span class="s">"Orange"</span><span class="o">,</span> <span class="s">"Banana"</span><span class="o">);</span>
<span class="nc">Map</span><span class="o"><</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Integer</span><span class="o">></span> <span class="n">stock</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Apple"</span><span class="o">,</span> <span class="mi">7</span><span class="o">,</span> <span class="s">"Orange"</span><span class="o">,</span> <span class="mi">20</span><span class="o">,</span> <span class="s">"Banana"</span><span class="o">,</span> <span class="mi">15</span><span class="o">);</span>
<span class="nc">Set</span><span class="o"><</span><span class="nc">Integer</span><span class="o">></span> <span class="n">numbers</span> <span class="o">=</span> <span class="nc">Set</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">,</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">,</span> <span class="mi">5</span><span class="o">);</span>
</code></pre></div></div>
<h3 id="optional-improvements">Optional improvements</h3>
<p>In Java 9 release Optional type received some love.</p>
<p>Three new methods were added to Optional class.</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">void stream()</code> method transforms optional to stream</li>
<li><code class="language-plaintext highlighter-rouge">void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)</code>`.
Same as ifPresent, but includes method to execute when optional empty.</li>
<li><code class="language-plaintext highlighter-rouge">Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)</code>.
It is similar to orElseGet, but instead of returning T object it returns
Optional<T>. Because of that, you can chain multiple or() methods.</T></li>
</ul>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Person</span> <span class="n">nameLess</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span><span class="s">"45122"</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span> <span class="kc">null</span><span class="o">);</span>
<span class="nc">Optional</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">firstName</span> <span class="o">=</span> <span class="nc">Optional</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">nameLess</span><span class="o">)</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="nl">Person:</span><span class="o">:</span><span class="n">getFirstName</span><span class="o">)</span>
<span class="o">.</span><span class="na">or</span><span class="o">(()</span> <span class="o">-></span> <span class="n">localNameResolver</span><span class="o">.</span><span class="na">resolveName</span><span class="o">(</span><span class="n">nameLess</span><span class="o">.</span><span class="na">getPersonalId</span><span class="o">()))</span>
<span class="o">.</span><span class="na">or</span><span class="o">(()</span> <span class="o">-></span> <span class="n">externalNameResolver</span><span class="o">.</span><span class="na">resolveName</span><span class="o">(</span><span class="n">nameLess</span><span class="o">.</span><span class="na">getPersonalId</span><span class="o">()));</span>
</code></pre></div></div>
<p>If person has missing name, then it will call localNameResolver.resolveName().
If this method returns empty Optional, then it will call externalNameResolver.resolveName().</p>
<h3 id="private-methods-in-interfaces">Private methods in interfaces</h3>
<p>Java 8 has introduced default method in interfaces. Java 9 added an ability to add
private method to interfaces. So if two default methods use duplicated code,
you can move that code to private method.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">HelloInterface</span> <span class="o">{</span>
<span class="k">default</span> <span class="nc">String</span> <span class="nf">helloWorld</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">hello</span><span class="o">(</span><span class="s">"World"</span><span class="o">);</span>
<span class="o">}</span>
<span class="k">default</span> <span class="nc">String</span> <span class="nf">helloJohn</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">hello</span><span class="o">(</span><span class="s">"John"</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="nc">String</span> <span class="nf">hello</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="nc">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"Hello %s!"</span><span class="o">,</span> <span class="n">name</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="process-api-improvements">Process API improvements</h3>
<p>Java 9 has some improvements to processes API. It has added a few method to
deal with system processes.</p>
<p>For example, it was painful to get PID, you had to write boilerplate code that
was OS dependent. Now it is easily retrievable using a single command.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">ProcessHandle</span> <span class="n">currentProcess</span> <span class="o">=</span> <span class="nc">ProcessHandle</span><span class="o">.</span><span class="na">current</span><span class="o">();</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">currentProcess</span><span class="o">.</span><span class="na">getPid</span><span class="o">())</span>
</code></pre></div></div>
<h3 id="reactive-streams-api">Reactive Streams API</h3>
<p>Java 9 has introduced Flow APIs. This will allow 3rd party vendors to implement
publish-subscribe frameworks. <a href="http://openjdk.java.net/jeps/266">JEP 266</a> specification
contains 4 interfaces located in <code class="language-plaintext highlighter-rouge">java.util.concurrent.Flow</code> class.</p>
<p>These interfaces include:</p>
<ul>
<li><a href="http://download.java.net/java/jdk9/docs/api/java/util/concurrent/Flow.Processor.html">Flow.Processor</a></li>
<li><a href="http://download.java.net/java/jdk9/docs/api/java/util/concurrent/Flow.Publisher.html">Flow.Publisher</a></li>
<li><a href="http://download.java.net/java/jdk9/docs/api/java/util/concurrent/Flow.Subscriber.html">Flow.Subscriber</a></li>
<li><a href="http://download.java.net/java/jdk9/docs/api/java/util/concurrent/Flow.Subscription.html">Flow.Subscription</a></li>
</ul>
<h3 id="minor-changes-that-probably-wont-be-noticed">Minor changes that probably won’t be noticed</h3>
<ul>
<li>Now you can get current java version by using <em>java –version</em>, instead of
<em>-version</em>. This operation will be compliant with Unix philosophy
because verbal operations should have two dashes before and
short hand operations should have single a dash.</li>
<li>Underscore character is reserved. You can’t create variable <code class="language-plaintext highlighter-rouge">_</code> anymore.
<a href="http://openjdk.java.net/jeps/213">JEP 213</a></li>
<li>Stack walking API <a href="http://openjdk.java.net/jeps/259">JEP 259</a></li>
<li>Applet API deprecation <a href="http://openjdk.java.net/jeps/289">JEP 289</a></li>
<li>@Deprecated annotation has new two fields. <strong>forRemoval</strong> and <strong>since</strong>.
<a href="http://openjdk.java.net/jeps/277">JEP 277</a></li>
<li>Default garbage collector was changed to G1. <a href="http://openjdk.java.net/jeps/248">JEP 248</a></li>
<li>Compact Strings <a href="http://openjdk.java.net/jeps/254">JEP 254</a></li>
<li>Java Platform Logging API <a href="http://openjdk.java.net/jeps/264">JEP 264</a></li>
<li>Try with resource improvements <a href="http://openjdk.java.net/jeps/213">JEP 213</a>.
<a href="/java/2017/12/27/java-try-with-resource#java-9-additions">My blog post on these changes</a></li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>I have mentioned most notable features. There are probably plenty features
that I have missed. For me, Java 9 release is quite an exciting one.</p>
<p>Modularization is a huge feature and in my opinion, it will take quite some time
to it being widely adopted.</p>
<p>Besides modularization Java 9 includes many small handy features. I’ll try to
adopt these new features in my code.</p>Dovydas VenckusJava 9 is a major release, which brings highly anticipated modularization.Failed assertThat throwing NoSuchMethodError exception when using Hamcrest and Mockito2017-09-24T14:40:00+00:002017-09-24T14:40:00+00:00https://www.dovydasvenckus.dev/junit/2017/09/24/hamcrest-mockito-failed-assert-mystic-message<p>From the start of my career, I have preferred Spock for writing tests.
While working with legacy systems I have written few JUnit tests here and there.
But my knowledge JUnit, Hamcrest, and Mockito is fairly limited.</p>
<p>At work, I had a task that involved teaching intern how to write unit tests using JUnit.</p>
<p>After setting up Gradle project I have noticed, that failed assertThat statements
threw <strong>java.lang.NoSuchMethodError</strong> exception with cryptic message.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
</code></pre></div></div>
<h2 id="example">Example</h2>
<p>It was gradle project with just 3 test dependencies.</p>
<p>build.gradle:</p>
<div class="language-gradle highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">apply</span> <span class="nl">plugin:</span> <span class="s1">'java'</span>
<span class="k">repositories</span> <span class="o">{</span>
<span class="n">jcenter</span><span class="o">()</span>
<span class="o">}</span>
<span class="k">dependencies</span> <span class="o">{</span>
<span class="n">testCompile</span> <span class="s1">'junit:junit:4.12'</span>
<span class="n">testCompile</span> <span class="s1">'org.mockito:mockito-all:1.10.19'</span>
<span class="n">testCompile</span> <span class="s1">'org.hamcrest:java-hamcrest:2.0.0.0'</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Test example:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.dovydasvenckus.hamcrest</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.junit.Test</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">static</span> <span class="n">org</span><span class="o">.</span><span class="na">hamcrest</span><span class="o">.</span><span class="na">Matchers</span><span class="o">.</span><span class="na">is</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">static</span> <span class="n">org</span><span class="o">.</span><span class="na">junit</span><span class="o">.</span><span class="na">Assert</span><span class="o">.</span><span class="na">assertThat</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">HamcrestMessageTest</span> <span class="o">{</span>
<span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">twoEqualsThree</span><span class="o">()</span> <span class="o">{</span>
<span class="n">assertThat</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">is</span><span class="o">(</span><span class="mi">3</span><span class="o">));</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Failed assertThat threw this cryptic exception.</p>
<h2 id="solution">Solution</h2>
<p>It fails because Mockito 1 depends on Hamcrest and JUnit has Hamcrest as a transient dependency.
So Mockito library starts using Hamcrest from JUnit. This causes described failure.</p>
<h3 id="solution-1-you-should-be-using-mockito-2">Solution 1. You should be using Mockito 2</h3>
<p>In this example, I have imported Mockito 1 version, because from Maven
repository I have accidentally selected mockito-all.jar. You should use mockito-core
jar to get Mockito 2. Mockito 2 does not depend on Hamcrest so this issue is resolved simply
by upgrading to Mockito 2.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>testCompile 'org.mockito:mockito-core:2.10.0'
</code></pre></div></div>
<h3 id="solution-2-importing-hamcrest-before-mockito">Solution 2. Importing Hamcrest before Mockito.</h3>
<p>If you work on legacy project and you can’t simply uplift the version, just import
Hamcrest before Mockito in build.gradle script.</p>
<p>Updated dependencies:</p>
<div class="language-gradle highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">dependencies</span> <span class="o">{</span>
<span class="n">testCompile</span> <span class="s1">'junit:junit:4.12'</span>
<span class="n">testCompile</span> <span class="s1">'org.hamcrest:java-hamcrest:2.0.0.0'</span>
<span class="n">testCompile</span> <span class="s1">'org.mockito:mockito-all:1.10.19'</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="result">Result</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java.lang.AssertionError:
Expected: is <3>
but: was <2>
</code></pre></div></div>
<p>Failed assert messages are solved by both of the solutions.</p>
<h2 id="final-thoughts">Final thoughts</h2>
<p>Both of these solutions fixes the problem.</p>
<p>Even if you’re working with legacy project I highly recommend upgrading to
the latest testing framework version.
There are some breaking changes, but if you won’t upgrade now, the migration will
be harder in future, when the new framework version is released.</p>
<p>My coworker has migrated quite a large project to Hamcrest 2.0 and Mockito 2.1,
that is actively developed. He managed to upgrade Mockito and Hamcrest versions
in a short period of time. There were more than 500 test files that had to be updated
because some functionality was removed or changed. This migration turned out fine,
without any major problems.</p>
<p>There are few things that I have learned from this migration:</p>
<ul>
<li>Before merging such big pull request I recommend to inform developer community,
so it won’t be a big surprise for them.</li>
<li>When undertaking such task be prepared for merge conflicts. You might need to
merge your pull request on weekend, if development is too active on working days.</li>
<li>Also, you might piss off some developers, that have OPEN pull requests,
because they might get merge conflicts after your changes were merged to master.
But I wouldn’t worry too much about that because you have done positive change to project.</li>
</ul>
<p>If you have any questions or insights feel free to leave a comment.</p>Dovydas VenckusFrom the start of my career, I have preferred Spock for writing tests. While working with legacy systems I have written few JUnit tests here and there. But my knowledge JUnit, Hamcrest, and Mockito is fairly limited.Lightweight REST API using Jersey on embedded Jetty server2017-08-20T14:00:00+00:002017-08-20T14:00:00+00:00https://www.dovydasvenckus.dev/rest/2017/08/20/jersey-on-embedded-jetty<p>In this tutorial, I’ll show how to setup REST web service using Jersey on
embedded Jetty server. For build tool, I’ll be using <a href="https://gradle.org/">Gradle</a>.
Also, we will package up this application as FatJar, single executable Jar for easy deployment.</p>
<p><a href="https://jersey.github.io/">Jersey</a> is <a href="https://github.com/jax-rs">JAX-RS</a> implementation.
This framework allows easy development of RESTful Web services.</p>
<p>Jetty is a lightweight HTTP server that can be easily embedded into the jar.</p>
<h2 id="example-project-source-code">Example project source code</h2>
<p>You can find the code used in this example in GitHub
<a href="https://github.com/blog-dovydasvenckus/jersey-with-embedded-jetty">repository</a>.</p>
<h2 id="project-structure">Project structure</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>tree
<span class="nb">.</span>
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
└── main
└── java
└── com
└── dovydasvenckus
└── jersey
├── greeting
│ └── Greeting.java
├── JerseyApplication.java
└── resources
└── HelloResource.java
</code></pre></div></div>
<p>This is a quite simple project structure. Most of the files are Gradle config files
and Gradle wrapper. We will be touching only 4 files: <em>build.gradle</em>, <em>Greeting.java</em>, <em>HelloResource.java</em>,
<em>JerseyApplication.java</em>.</p>
<h2 id="build-config">Build config</h2>
<p>This is how <em>build.gradle</em> file looks like:</p>
<div class="language-gradle highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">apply</span> <span class="nl">plugin:</span> <span class="s1">'java'</span>
<span class="n">apply</span> <span class="nl">plugin:</span> <span class="s1">'application'</span>
<span class="n">apply</span> <span class="nl">plugin:</span> <span class="s1">'com.github.johnrengelman.shadow'</span>
<span class="n">sourceCompatibility</span> <span class="o">=</span> <span class="mf">1.8</span>
<span class="n">mainClassName</span> <span class="o">=</span> <span class="s1">'com.dovydasvenckus.jersey.JerseyApplication'</span>
<span class="n">ext</span> <span class="o">{</span>
<span class="n">slf4jVersion</span> <span class="o">=</span> <span class="s1">'1.7.25'</span>
<span class="n">jettyVersion</span> <span class="o">=</span> <span class="s1">'9.4.6.v20170531'</span>
<span class="n">jerseyVersion</span> <span class="o">=</span> <span class="s1">'2.27'</span>
<span class="o">}</span>
<span class="k">buildscript</span> <span class="o">{</span>
<span class="k">repositories</span> <span class="o">{</span>
<span class="n">jcenter</span><span class="o">()</span>
<span class="o">}</span>
<span class="k">dependencies</span> <span class="o">{</span>
<span class="n">classpath</span> <span class="s1">'com.github.jengelman.gradle.plugins:shadow:2.0.1'</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">repositories</span> <span class="o">{</span>
<span class="n">jcenter</span><span class="o">()</span>
<span class="o">}</span>
<span class="k">dependencies</span> <span class="o">{</span>
<span class="n">compile</span> <span class="s2">"org.slf4j:slf4j-api:${slf4jVersion}"</span>
<span class="n">compile</span> <span class="s2">"org.slf4j:slf4j-simple:${slf4jVersion}"</span>
<span class="n">compile</span> <span class="s2">"org.eclipse.jetty:jetty-server:${jettyVersion}"</span>
<span class="n">compile</span> <span class="s2">"org.eclipse.jetty:jetty-servlet:${jettyVersion}"</span>
<span class="n">compile</span> <span class="s2">"org.glassfish.jersey.core:jersey-server:${jerseyVersion}"</span>
<span class="n">compile</span> <span class="s2">"org.glassfish.jersey.containers:jersey-container-servlet-core:${jerseyVersion}"</span>
<span class="n">compile</span> <span class="s2">"org.glassfish.jersey.containers:jersey-container-jetty-http:${jerseyVersion}"</span>
<span class="n">compile</span> <span class="s2">"org.glassfish.jersey.media:jersey-media-json-jackson:${jerseyVersion}"</span>
<span class="n">compile</span> <span class="s2">"org.glassfish.jersey.inject:jersey-hk2:${jerseyVersion}"</span>
<span class="o">}</span>
</code></pre></div></div>
<p>I think Gradle file is pretty self-explanatory. Probably only thing you should change
is mainClassName variable to point to your main class that will initialize Jetty server.</p>
<p>JSON parsing is done by using popular <a href="https://github.com/FasterXML/jackson">Jackson</a> library.
Including <code class="language-plaintext highlighter-rouge">jersey-media-json-jackson</code> package in classpath will take care of JSON marshaling and unmarshaling.</p>
<h2 id="server-configuration">Server configuration</h2>
<p>In JerseyApplication I have configured Jetty and Jersey.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.dovydasvenckus.jersey</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.eclipse.jetty.server.Server</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.eclipse.jetty.servlet.ServletContextHandler</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.eclipse.jetty.servlet.ServletHolder</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.glassfish.jersey.servlet.ServletContainer</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.slf4j.Logger</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.slf4j.LoggerFactory</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">static</span> <span class="n">org</span><span class="o">.</span><span class="na">eclipse</span><span class="o">.</span><span class="na">jetty</span><span class="o">.</span><span class="na">servlet</span><span class="o">.</span><span class="na">ServletContextHandler</span><span class="o">.</span><span class="na">NO_SESSIONS</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">JerseyApplication</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="nc">Logger</span> <span class="n">logger</span> <span class="o">=</span> <span class="nc">LoggerFactory</span><span class="o">.</span><span class="na">getLogger</span><span class="o">(</span><span class="nc">JerseyApplication</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">Server</span> <span class="n">server</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Server</span><span class="o">(</span><span class="mi">8080</span><span class="o">);</span>
<span class="nc">ServletContextHandler</span> <span class="n">servletContextHandler</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ServletContextHandler</span><span class="o">(</span><span class="no">NO_SESSIONS</span><span class="o">);</span>
<span class="n">servletContextHandler</span><span class="o">.</span><span class="na">setContextPath</span><span class="o">(</span><span class="s">"/"</span><span class="o">);</span>
<span class="n">server</span><span class="o">.</span><span class="na">setHandler</span><span class="o">(</span><span class="n">servletContextHandler</span><span class="o">);</span>
<span class="nc">ServletHolder</span> <span class="n">servletHolder</span> <span class="o">=</span> <span class="n">servletContextHandler</span><span class="o">.</span><span class="na">addServlet</span><span class="o">(</span><span class="nc">ServletContainer</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="s">"/api/*"</span><span class="o">);</span>
<span class="n">servletHolder</span><span class="o">.</span><span class="na">setInitOrder</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
<span class="n">servletHolder</span><span class="o">.</span><span class="na">setInitParameter</span><span class="o">(</span>
<span class="s">"jersey.config.server.provider.packages"</span><span class="o">,</span>
<span class="s">"com.dovydasvenckus.jersey.resources"</span>
<span class="o">);</span>
<span class="k">try</span> <span class="o">{</span>
<span class="n">server</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
<span class="n">server</span><span class="o">.</span><span class="na">join</span><span class="o">();</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">Exception</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span>
<span class="n">logger</span><span class="o">.</span><span class="na">error</span><span class="o">(</span><span class="s">"Error occurred while starting Jetty"</span><span class="o">,</span> <span class="n">ex</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">exit</span><span class="o">(</span><span class="mi">1</span><span class="o">);</span>
<span class="o">}</span>
<span class="k">finally</span> <span class="o">{</span>
<span class="n">server</span><span class="o">.</span><span class="na">destroy</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Server server = new Server(8080);
</code></pre></div></div>
<p>Sets server port to 8080.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ServletContextHandler servletContextHandler = new ServletContextHandler(NO_SESSIONS);
</code></pre></div></div>
<p>To use jetty you must create ServletContextHandler. In this particular instance, we
created handler without sessions, because REST is stateless.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>servletContextHandler.setContextPath("/");
</code></pre></div></div>
<p>Sets application path to the root.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ServletHolder servletHolder = servletContextHandler.addServlet(ServletContainer.class, "/api/*");
</code></pre></div></div>
<p>This adds Servlet that will handle requests on /api/*. That means our Web services
will be accessible using /api/{resource} path.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>servletHolder.setInitParameter(
"jersey.config.server.provider.packages",
"com.dovydasvenckus.jersey.resources"
);
</code></pre></div></div>
<p>This is an important step. You must set package where rest resources are located.</p>
<h2 id="greeting-pojo">Greeting POJO</h2>
<p>This simple <a href="https://en.wikipedia.org/wiki/Plain_old_Java_object">POJO</a> will
be used as transfer class. It will be marshaled to JSON and unmarshaled from JSON.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.dovydasvenckus.jersey.greeting</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Greeting</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">message</span><span class="o">;</span>
<span class="nc">Greeting</span><span class="o">()</span> <span class="o">{</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nf">Greeting</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">message</span> <span class="o">=</span> <span class="n">getGreeting</span><span class="o">(</span><span class="n">name</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getMessage</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">message</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setMessage</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">message</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="nf">getGreeting</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="s">"Hello "</span> <span class="o">+</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>You must create default no args constructors for classes that will be marshaled
and unmarshaled.</p>
<h2 id="rest-resource">REST resource</h2>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.dovydasvenckus.jersey.resources</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.dovydasvenckus.jersey.greeting.Greeting</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.ws.rs.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.ws.rs.core.MediaType</span><span class="o">;</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"/hello"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">HelloResource</span> <span class="o">{</span>
<span class="nd">@GET</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"/{param}"</span><span class="o">)</span>
<span class="nd">@Produces</span><span class="o">(</span><span class="nc">MediaType</span><span class="o">.</span><span class="na">APPLICATION_JSON</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">Greeting</span> <span class="nf">hello</span><span class="o">(</span><span class="nd">@PathParam</span><span class="o">(</span><span class="s">"param"</span><span class="o">)</span> <span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Greeting</span><span class="o">(</span><span class="n">name</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@POST</span>
<span class="nd">@Produces</span><span class="o">(</span><span class="nc">MediaType</span><span class="o">.</span><span class="na">TEXT_PLAIN</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">helloUsingJson</span><span class="o">(</span><span class="nc">Greeting</span> <span class="n">greeting</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">greeting</span><span class="o">.</span><span class="na">getMessage</span><span class="o">()</span> <span class="o">+</span> <span class="s">"\n"</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This resource is located <code class="language-plaintext highlighter-rouge">/api/hello</code>. There are two endpoints.
First uses GET method, takes string path param and returns JSON.
Second uses POST method, parses JSON and returns plain text.</p>
<h2 id="building">Building</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./gradlew build
</code></pre></div></div>
<p>It should build FatJar in build/libs directory. The jar should be named {application-name}-all.jar.
In this case, jar was named jersey-with-embedded-jetty-all.jar. You can find the application name
in settings.gradle, under rootProject.name property.</p>
<h2 id="running">Running</h2>
<p>Launch it like any normal executable jar.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java -jar build/libs/jersey-with-embedded-jetty-all.jar
</code></pre></div></div>
<p>It should start successfully on port 8080.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[main] INFO org.eclipse.jetty.util.log - Logging initialized @51ms to org.eclipse.jetty.util.log.Slf4jLog
[main] INFO org.eclipse.jetty.server.Server - jetty-9.4.z-SNAPSHOT
[main] INFO org.eclipse.jetty.server.handler.ContextHandler - Started o.e.j.s.ServletContextHandler@f0c8a99{/,null,AVAILABLE}
[main] INFO org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@3e27ba32{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
[main] INFO org.eclipse.jetty.server.Server - Started @467ms
</code></pre></div></div>
<h2 id="testing-web-service">Testing web service</h2>
<h3 id="json-unparsing">JSON unparsing</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl localhost:8080/api/hello/John
<span class="o">{</span><span class="s2">"message"</span>:<span class="s2">"Hello John"</span><span class="o">}</span>
</code></pre></div></div>
<p>Using a Linux tool curl I have send GET request to <code class="language-plaintext highlighter-rouge">/api/hello/John</code>
and received JSON response that contains message “Hello John”.</p>
<h3 id="json-parsing">JSON parsing</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="nt">-X</span> POST <span class="nt">-d</span> <span class="s1">'{"message": "Hello John"}'</span> http://localhost:8080/api/hello
Hello John
</code></pre></div></div>
<p>Sending POST method with JSON body returns correct plain text response.</p>
<h2 id="final-thoughts">Final thoughts</h2>
<p>That’s it. It is pretty straightforward to create a lightweight REST API using
Jersey and Jetty, without any heavyweight framework.</p>
<p>If you have any questions feel free to drop them in the comment section below.</p>Dovydas VenckusIn this tutorial, I’ll show how to setup REST web service using Jersey on embedded Jetty server. For build tool, I’ll be using Gradle. Also, we will package up this application as FatJar, single executable Jar for easy deployment.Netlify static web site hosting2017-08-17T19:52:15+00:002017-08-17T19:52:15+00:00https://www.dovydasvenckus.dev/web-hosting/2017/08/17/netlify-static-web-hosting<p>Static site generators are really good for blogging sites. You generate site once
and you simply serve generated HTML files using HTTP server.</p>
<p>There are at least a few dozens of static site generators. For this blog, I have chosen
to use Jekyll, because it is quite popular and well documented.</p>
<h2 id="why-should-you-consider-static-websites">Why should you consider static websites</h2>
<p>Static site load times are fast because you don’t waste time to render a web page for every request.
Also by using a static site, you totally skip other layers like database.</p>
<p>For some people, static blog might look too static because you can’t add dynamic content.
The most common example is comments. The easiest way to solve this problem is to
use a 3rd party comment library. E.g <a href="https://disqus.com/">Disqus</a>. Of course,if you don’t
like 3rd party libraries for privacy reasons you could develop REST API for comment
management and implement comment rendering in JavaScript.</p>
<p>Another thing I love about static websites is versioning. Because your content
is just a bunch of markup files you can easily version your website using
your favorite versioning system e.g. git, mercurial.</p>
<p>The deployment process is a breeze when you are using git or other versioning systems
that allow executing commands after you push code to the repository. After pushing
your code to the remote, it triggers a command to generate static site and after a short
period of time, your changes are live.</p>
<h2 id="why-i-have-chosen-netlify-as-my-blog-hosting">Why I have chosen Netlify as my blog hosting?</h2>
<p><a href="https://netlify.com">Netlify</a> CDN. Netlify hosts your website in multiple servers that
are located in different geographical locations. This minimizes load times for users
because content is a served from the server that is nearest to their geographical position.</p>
<p>Netlify is easily configurable you can select which branch you want to deploy on
git push. You have access system ENV variables. Also, it should support a wide variety
of site generators, because you have access to change the command that builds your site.</p>
<p>On top of easy deployment, you get ability to rollback your site to the previous version
using web interface.</p>
<p>It even has a prerendering option for single page apps. It should help Google web
crawlers to scan your dynamic site.</p>
<p>One click SSL certificate configuration using Let’s encrypt. I’m a huge fan of
<a href="/security/2017/08/16/lets-encrypt/">Let’s encrypt</a>.</p>
<p>And all these features are accessible for free.</p>
<h2 id="final-thoughts">Final thoughts</h2>
<p>I only scratched the surface of features that Netlify provides. But I really like
the simplicity and ease of use of their service.</p>Dovydas VenckusStatic site generators are really good for blogging sites. You generate site once and you simply serve generated HTML files using HTTP server.Let’s encrypt is awesome. Free SSL for everyone!2017-08-16T19:48:42+00:002017-08-16T19:48:42+00:00https://www.dovydasvenckus.dev/security/2017/08/16/lets-encrypt<p><img src="/assets/images/2017-08-16-lets-encrypt/firefox-no-cert.png" /></p>
<p>I’m sure that we all have seen this window more than once. After you created an app
with your sweat and tears it’s time to deploy it. And to avoid this ugly window
you will need to acquire SSL certificate that web browser will trust.</p>
<p>In my experience SSL certificates were a pain in the ass. You had to acquire them by buying,
and you had to configure your HTTP server to use the certificate.</p>
<h2 id="lets-encrypt---the-game-changer">Let’s encrypt - the game changer</h2>
<p><a href="https://letsencrypt.org/">Let’s encrypt</a> is certificate authority. It is a nonprofit organization that provides
<em>domain validation certificates</em> for free.</p>
<p>Even better, it provides free SSL certificates in a fully automated way. It uses
<a href="https://github.com/ietf-wg-acme/acme/">ACME</a> protocol. To acquire certificate
you need to use ACME client. For this, you can use official Let’s encrypt client
<a href="https://certbot.eff.org/">certbot</a>.</p>
<p>On top of that, all <strong>Let’s encrypt</strong> embraces open source mindset and publishes
their code on GitHub. They even have open sourced their ACME <a href="https://github.com/letsencrypt/boulder">server</a>.</p>
<p>Also, Let’s encrypt have partnered up with some hosting providers to provide
their SSL certificates by default. One of the providers that I personally use is
<a href="https://www.netlify.com">netlify</a></p>
<h2 id="acquiring-certificate-using-certbot">Acquiring certificate using certbot</h2>
<p>Certbot has automatized certificate issuance and configuration for most popular HTTP servers.
It includes Apache, Nginx support.</p>
<p>For example, to acquire SSL certificate and configure HTTPS on Nginx server using
Arch Linux I ran these commands:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -S certbot-nginx
sudo certbot --nginx
</code></pre></div></div>
<p>The first command installs certbot.</p>
<p>The last command launches an interactive installer that asks a few questions before
acquiring SSL certificate.</p>
<p>That’s it, it’s stupidly simple. After restart Nginx should use new SSL certificate.
I recommend to reviewing config files to make sure it configured it correctly.</p>
<h2 id="renewing-certificate-using-certbot">Renewing certificate using certbot</h2>
<p>Let’s encrypt certificates are valid only for 90 days. But it is really easy
to auto-renew this certificate.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>certbot renew
</code></pre></div></div>
<p>This command renews all certificates that were issued using certbot.</p>
<p>To automate this process, you can add this command to cron.</p>
<p>My crontab:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0 0 3 * * ? /usr/bin/certbot renew --quiet
</code></pre></div></div>
<p>This cron job will be run every day at 3 AM.</p>
<h2 id="some-caveats">Some caveats</h2>
<p>I’m not saying that Let’s encrypt made other certificate providers obsolete.
Let’s encrypt only provides <em>domain validation certificates</em>. They do not provide
<em>organization validation certificates</em> and other types, because they can’t automate
issuing of these certificates.</p>
<p>Certificates are valid for only 90 days. But as I have written it is easy to renew
them automatically.</p>
<p>Currently, Let’s encrypt does not support wildcard certificates. But they have
<a href="https://letsencrypt.org/2017/07/06/wildcard-certificates-coming-jan-2018.html">promised</a>
to add support in January of 2018.</p>
<p>Older Java versions did not trust Let’s encrypt certificates by <a href="https://community.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/60">default</a>.
But it was fixed in Java 7 and Java 8 versions. So if you are running latest revision of
these versions you should be fine.</p>
<p>Automatic certificate renewing does not work when your server is behind <a href="https://www.cloudflare.com/">CloudFlare</a>
or other similar services. In that case, renewing certificate involves manual work.
<a href="http://infosec.theos-blog.com/renewing-letsencrypt-certificate-when-using-cloudflare/">This is great article</a>
on renewing certificate, when the server is behind <a href="https://www.cloudflare.com/">CloudFlare</a>.</p>
<h2 id="final-thoughts">Final thoughts</h2>
<p>I’m really impressed by what Let’s encrypt has done. They made HTTPS accessible for everyone.
I believe that free SSL and automated issuance is a huge step toward widespread
HTTPS adoption and safer web.</p>
<p>P.S. From now on this blog uses HTTPS using an SSL certificate provided by Let’s encrypt.
I’m really grateful for their service.</p>Dovydas VenckusShrinking XFS partition2017-08-05T20:59:59+00:002017-08-05T20:59:59+00:00https://www.dovydasvenckus.dev/linux/2017/08/05/shrink-xfs<p>XFS is a fairly popular file system on Linux.</p>
<p>Ability to shrink partitions might be useful in cases when you need to shrink one partition
and expand another one.
I had a problem where my root partition was too small, so the only way to expand root partition
was to shrink home and expand root file system.</p>
<p>To manipulate XFS partitions you might need to install <strong>xfsprogs</strong> package. You can grow partition size
using <a href="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/xfsgrow.html">xfs_growfs</a>.
But unlike EXT4 file system there is no way to shrink partition. Good luck you’re fucked.</p>
<h2 id="solution">Solution</h2>
<p>But there is a solution how to shrink partition. It’s not a straightforward solution,
but it saved my hide, when my root partition was way too small.</p>
<ol>
<li>Backup partition image</li>
<li>Delete old partition</li>
<li>Create new smaller partition (make sure that image still fits partition)</li>
<li>Restore image</li>
<li>Edit fstab</li>
</ol>
<h3 id="example">Example</h3>
<p>For this example, I have created a virtual machine with Ubuntu installation.
There is /home (/dev/sda5) and / (/dev/sda1) partitions. In this case we will be shrinking home
partition from ~8.6GB to 4GB.</p>
<p>List of partitions:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@ubuntu:/home/ubuntu# fdisk -l
...
Disk /dev/sda: 16 GiB, 17179869184 bytes, 33554432 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x577dacac
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 15624191 15622144 7.5G 83 Linux
/dev/sda2 15626238 33552383 17926146 8.6G 5 Extended
/dev/sda5 15626240 33552383 17926144 8.6G 83 Linux
Disk /dev/sdb: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 95A2ABE1-743B-4A77-9133-7EF3B3AF6F5A
Device Start End Sectors Size Type
/dev/sdb1 2048 8388574 8386527 4G Linux filesystem
</code></pre></div></div>
<p>As you can see from partition list, there is /dev/sdb1 this partition will be used
to back up our /home partition.</p>
<h3 id="preparation">Preparation</h3>
<p>Probably you could shrink home partition using live system.
But if you would like to shrink root partition you could not do it on a live system.</p>
<p>So in this example, I will demonstrate a method that should work even with resizing root partition.
For this to work you’ll need to boot not from your hard drive, but from Live USB stick or CD.</p>
<p>In this case, I have chosen to use <strong>Live Ubuntu CD</strong>.</p>
<p>When you are running from the Live CD open terminal and change to root, because most
of the commands require root access.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo su
</code></pre></div></div>
<h3 id="backing-up-image">Backing up image</h3>
<p>For creating disk images I have chosen to use <a href="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Storage_Administration_Guide/xfsbackuprestore.html"><strong>xfsdump</strong></a> application. It allows
creating a backup of mounted file system. In most distributions <strong>xfsdump</strong> and
<strong>xfsrestore</strong> are not installed by default.</p>
<p>Install <strong>xfsdump</strong> and <strong>xfsrestore</strong>:
apt-get install xfsdump</p>
<p>Before making an image of home partition we need to mount it.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir /mnt/home
mount /dev/sda5 /mnt/home
</code></pre></div></div>
<p>Also, we need to mount destination partition. This partition should be big enough
to hold the backup image.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir /mnt/external
mount /dev/sdb1 /mnt/external
</code></pre></div></div>
<p>Backup image creation:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xfsdump -l 0 -f /mnt/external/backup /mnt/home
</code></pre></div></div>
<p>When running xfs dump you must specify the backup file name. In this case image name is
<strong>backup</strong>.</p>
<p>After running this command you’ll be asked to enter the label of backup. In this case
I have used “home” as label.</p>
<h3 id="delete-old-partition">Delete old partition</h3>
<p>Unmount home partition.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>umount /mnt/home
</code></pre></div></div>
<p>To delete the partition you can use your favorite application. It can be GParted or
another tool.</p>
<p>In this example, I have used interactive command line utility fdisk.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fdisk /dev/sda
Welcome to fdisk (util-linux 2.29).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): d
Partition number (1,2,5, default 5): 5
Partition 5 has been deleted.
</code></pre></div></div>
<p><strong>d</strong> stands for delete. <strong>5th</strong> partition is home partition</p>
<p>Press <strong>w</strong> to write changes to disk.</p>
<h3 id="create-new-smaller-partition">Create new smaller partition</h3>
<p>To create new partition you can use any tool you like, but for this example I have
chose fdisk.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fdisk /dev/sda
Welcome to fdisk (util-linux 2.29).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 5
First sector (15628286-33552383, default 15628288): (enter)
Last sector, +sectors or +size{K,M,G,T,P} (15628288-33552383, default 33552383): +4G
Created a new partition 5 of type 'Linux' and of size 4 GiB.
</code></pre></div></div>
<p><strong>n</strong> command is for creating new partition. <strong>+4G</strong> means that new partition size will be 4GB.</p>
<p>Press <strong>w</strong> to write changes to disk.</p>
<p>Create XFS file system on new partition:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkfs.xfs /dev/sda5
</code></pre></div></div>
<p>Mount partition:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> mount /dev/sda5 /mnt/home
</code></pre></div></div>
<h3 id="restore-image">Restore image</h3>
<p>To restore XFS partition you need to know session ID. To find out image session id
run this command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xfsrestore -I | grep session
</code></pre></div></div>
<p>Output of this command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>session 0:
session label: "home"
session id: 7a80f19f-ab34-4598-bf8f-dede406d50dc
</code></pre></div></div>
<p>So in our case session id is 7a80f19f-ab34-4598-bf8f-dede406d50dc.</p>
<p>Run <code class="language-plaintext highlighter-rouge">xfsrestore</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xfsrestore -f /mnt/external/backup -S 7a80f19f-ab34-4598-bf8f-dede406d50dc /mnt/home
</code></pre></div></div>
<p>Output:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dede406d50dc /mnt/home
xfsrestore: using file dump (drive_simple) strategy
...
xfsrestore: Restore Summary:
xfsrestore: stream 0 /mnt/external/backup OK (success)
xfsrestore: Restore Status: SUCCESS
</code></pre></div></div>
<h3 id="edit-fstab">Edit fstab</h3>
<p>The new partition will have different UUID, because of that your system might <strong>not boot</strong>.</p>
<p>When you are shrinking <strong>/home</strong>, <strong>/root</strong> or other automatically mounted partition
you’ll need to update <strong>fstab</strong> with new partition UUID.</p>
<p>Before rebooting mount your root file system and edit fstab file.</p>
<p>Run <code class="language-plaintext highlighter-rouge">blkid</code> to find out current UUID of disk.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>blkid
/dev/sr0: UUID="2017-04-12-03-44-04-00" LABEL="Ubuntu 17.04 amd64" TYPE="iso9660" PTUUID="1b571474" PTTYPE="dos"
/dev/loop0: TYPE="squashfs"
/dev/sda1: UUID="3d2b0c24-2aae-4eb6-ae76-b15f3aca32f4" TYPE="xfs" PARTUUID="577dacac-01"
/dev/sda5: UUID="f359a7c4-bc72-416d-a50a-5869792c2832" TYPE="xfs" PARTUUID="577dacac-05"
/dev/sdb1: UUID="0882a8db-ae76-44de-9bbe-a453c727ff50" TYPE="xfs" PARTUUID="9f306132-b5fc-4bd5-8a85-a3f9d820276a"
</code></pre></div></div>
<p>In this case new UUID is <code class="language-plaintext highlighter-rouge">0882a8db-ae76-44de-9bbe-a453c727ff50</code>. You should replace
your partition UUID in fstab with your new partitions UUID.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir /mnt/root
mount /dev/sda1 /mnt/root
vim /mnt/root/etc/fstab
</code></pre></div></div>
<h3 id="summary">Summary</h3>
<p>That’s it, the solution was a little bit long-winded, but at least it works.
If you know a simpler way to resize XFS partition feel free to share it in the
comments section.</p>Dovydas VenckusXFS is a fairly popular file system on Linux.Finding biggest tables in MySQL and PostgreSQL2017-07-23T16:02:59+00:002017-07-23T16:02:59+00:00https://www.dovydasvenckus.dev/rdbms/2017/07/23/rdbms-table-size-measurment<p>In relational database systems, we store large amounts of data.
Ability to find biggest tables in a database is quite useful when you are searching
where your precious disk space is being used.</p>
<p>In this blog post, I’ll show how to list biggest tables in MariaDB and PostgreSQL.</p>
<h2 id="mariadbmysql">MariaDB/MySQL</h2>
<p>In MySQL and MariaDB information about table size is stored in table <strong>TABLES</strong>
which resides in <strong>information_schema</strong>.</p>
<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><span class="k">SELECT</span>
<span class="k">TABLE_NAME</span> <span class="k">AS</span> <span class="s1">'Table'</span><span class="p">,</span>
<span class="n">ROUND</span><span class="p">(</span><span class="n">DATA_LENGTH</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">)</span> <span class="k">AS</span> <span class="s1">'Table Size (KB)'</span><span class="p">,</span>
<span class="n">ROUND</span><span class="p">(</span><span class="n">INDEX_LENGTH</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">)</span> <span class="k">AS</span> <span class="s1">'Index Size (KB)'</span><span class="p">,</span>
<span class="n">ROUND</span><span class="p">(</span><span class="n">DATA_FREE</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">)</span> <span class="k">AS</span> <span class="s1">'Data free (KB)'</span><span class="p">,</span>
<span class="n">ROUND</span><span class="p">((</span><span class="n">DATA_LENGTH</span> <span class="o">+</span> <span class="n">INDEX_LENGTH</span> <span class="o">+</span> <span class="n">DATA_FREE</span><span class="p">)</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">)</span> <span class="k">AS</span> <span class="s1">'Total Size (KB)'</span>
<span class="k">FROM</span> <span class="n">information_schema</span><span class="p">.</span><span class="n">TABLES</span>
<span class="k">WHERE</span> <span class="n">TABLE_SCHEMA</span> <span class="o">=</span> <span class="s1">'your_schema_name'</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="p">(</span><span class="n">DATA_LENGTH</span> <span class="o">+</span> <span class="n">INDEX_LENGTH</span><span class="p">)</span> <span class="k">DESC</span>
<span class="k">LIMIT</span> <span class="mi">10</span><span class="p">;</span></code></pre></figure>
<p>Before running this query don’t forget to set <strong>TABLE_SCHEMA</strong> to your database name.</p>
<p>When you are querying table size you should analyze these 3 columns:</p>
<ul>
<li>DATA_LENGTH - this field shows how much space is occupied by data + <a href="https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html">clustered index</a>.</li>
<li>INDEX_LENGTH - this field shows how much of space is used for <a href="https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html">secondary indexes</a>.</li>
<li>DATA_FREE - shows allocated, but not used pages.</li>
</ul>
<p>Example of query result:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+---------+-----------------+-----------------+----------------+-----------------+
| Table | Table Size (KB) | Index Size (KB) | Data free (KB) | Total Size (KB) |
+---------+-----------------+-----------------+----------------+-----------------+
| article | 23056 | 0 | 4096 | 27152 |
| client | 176 | 64 | 0 | 240 |
| item | 112 | 0 | 0 | 112 |
+---------+-----------------+-----------------+----------------+-----------------+
</code></pre></div></div>
<h2 id="postgresql">PostgreSQL</h2>
<p>In PostgreSQL required data is stored in <strong>pg_class</strong> table.</p>
<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><span class="k">SELECT</span> <span class="k">table_name</span><span class="p">,</span>
<span class="n">table_bytes</span> <span class="o">/</span> <span class="mi">1024</span> <span class="k">AS</span> <span class="n">TABLE_KB</span><span class="p">,</span>
<span class="n">index_bytes</span> <span class="o">/</span> <span class="mi">1024</span> <span class="k">AS</span> <span class="n">INDEX_KB</span><span class="p">,</span>
<span class="n">toast_bytes</span> <span class="o">/</span> <span class="mi">1024</span> <span class="k">AS</span> <span class="n">TOAST_KB</span><span class="p">,</span>
<span class="n">total_bytes</span> <span class="o">/</span> <span class="mi">1024</span> <span class="k">AS</span> <span class="n">TOTAL_KB</span>
<span class="k">FROM</span> <span class="p">(</span>
<span class="k">SELECT</span> <span class="o">*</span><span class="p">,</span>
<span class="n">total_bytes</span> <span class="o">-</span> <span class="n">index_bytes</span> <span class="o">-</span> <span class="n">toast_bytes</span>
<span class="k">AS</span> <span class="n">table_bytes</span> <span class="k">FROM</span> <span class="p">(</span>
<span class="k">SELECT</span> <span class="k">c</span><span class="p">.</span><span class="n">oid</span><span class="p">,</span><span class="n">nspname</span> <span class="k">AS</span> <span class="n">table_schema</span><span class="p">,</span> <span class="n">relname</span> <span class="k">AS</span> <span class="k">TABLE_NAME</span><span class="p">,</span>
<span class="n">pg_total_relation_size</span><span class="p">(</span><span class="k">c</span><span class="p">.</span><span class="n">oid</span><span class="p">)</span> <span class="k">AS</span> <span class="n">total_bytes</span><span class="p">,</span>
<span class="n">pg_indexes_size</span><span class="p">(</span><span class="k">c</span><span class="p">.</span><span class="n">oid</span><span class="p">)</span> <span class="k">AS</span> <span class="n">index_bytes</span><span class="p">,</span>
<span class="n">COALESCE</span><span class="p">(</span><span class="n">pg_total_relation_size</span><span class="p">(</span><span class="n">reltoastrelid</span><span class="p">),</span> <span class="mi">0</span><span class="p">)</span> <span class="k">AS</span> <span class="n">toast_bytes</span>
<span class="k">FROM</span> <span class="n">pg_class</span> <span class="k">c</span>
<span class="k">LEFT</span> <span class="k">JOIN</span> <span class="n">pg_namespace</span> <span class="n">n</span> <span class="k">ON</span> <span class="n">n</span><span class="p">.</span><span class="n">oid</span> <span class="o">=</span> <span class="k">c</span><span class="p">.</span><span class="n">relnamespace</span>
<span class="k">WHERE</span> <span class="n">relkind</span> <span class="o">=</span> <span class="s1">'r'</span> <span class="k">AND</span> <span class="n">nspname</span><span class="o">=</span><span class="s1">'public'</span>
<span class="p">)</span> <span class="n">a</span>
<span class="p">)</span> <span class="n">a</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="n">total_bytes</span> <span class="k">DESC</span>
<span class="k">LIMIT</span> <span class="mi">10</span><span class="p">;</span></code></pre></figure>
<p>When you are using this query, you should take into account these fields:</p>
<ul>
<li>TABLE_KB - this field shows how much of space is occupied by data.</li>
<li>INDEX_KB - space used by index. Unlike MySQL, it includes space used by clustered indexes.</li>
<li>TOAST_KB - Space used for TOAST. PostgreSQL stores long values such as strings and byte arrays in.
separate TOAST tables. This technique is called <a href="https://www.postgresql.org/docs/9.6/static/storage-toast.html">TOAST</a>.</li>
<li>TOTAL_KB - this field shows the total space used for a table.</li>
</ul>
<p>Example of this query result:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table_name | table_kb | index_kb | toast_kb | total_kb
-----------+----------+----------+----------+----------
article | 328 | 40 | 5352 | 5720
client | 176 | 96 | 8 | 280
item | 128 | 40 | 0 | 168
</code></pre></div></div>
<h2 id="final-thoughts">Final thoughts</h2>
<p>These queries were quite useful for my personal usage. I hope it will bring some
value to you.</p>
<p>For this article, I have used KB as measurement units. If you want to use different
measurement unit, feel free to modify these queries.</p>
<p>If you have some questions or you know a better way, please leave a comment.</p>Dovydas VenckusIn relational database systems, we store large amounts of data. Ability to find biggest tables in a database is quite useful when you are searching where your precious disk space is being used.Lambda != method reference2016-11-04T21:02:59+00:002016-11-04T21:02:59+00:00https://www.dovydasvenckus.dev/java/2016/11/04/lambda-not-equals-method-reference<p>Most of the IDE’s give you hints, that you could replace lambdas with method references.
But there is a subtle difference between them.</p>
<p>I was refactoring commit at work on Vaadin application.
To improve readability I started replacing lambdas with method references.
After refactoring, and testing I noticed, that button click action resulted in NullPointerException.</p>
<h2 id="example">Example</h2>
<p>In this example, I’ll try to show the difference between lambda expression and method reference.</p>
<h3 id="lambda">Lambda</h3>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.dovydasvenckus.lambda</span><span class="o">;</span>
<span class="kd">class</span> <span class="nc">MyCoolClass</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">doSomething</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"My cool function invoked"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
<span class="kd">static</span> <span class="nc">MyCoolClass</span> <span class="n">myCoolClass</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">Runnable</span> <span class="n">runnable</span> <span class="o">=</span> <span class="o">()</span> <span class="o">-></span> <span class="n">myCoolClass</span><span class="o">.</span><span class="na">doSomething</span><span class="o">();</span>
<span class="n">myCoolClass</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MyCoolClass</span><span class="o">();</span>
<span class="n">runnable</span><span class="o">.</span><span class="na">run</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<h4 id="output">Output:</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>My cool function invoked
</code></pre></div></div>
<h3 id="method-reference">Method reference</h3>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">Runnable</span> <span class="n">runnable</span> <span class="o">=</span> <span class="nl">myCoolClass:</span><span class="o">:</span><span class="n">doSomething</span><span class="o">;</span>
<span class="n">myCoolClass</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MyCoolClass</span><span class="o">();</span>
<span class="n">runnable</span><span class="o">.</span><span class="na">run</span><span class="o">();</span></code></pre></figure>
<h4 id="output-1">Output:</h4>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">Exception</span> <span class="n">in</span> <span class="n">thread</span> <span class="s">"main"</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">NullPointerException</span>
<span class="n">at</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">Objects</span><span class="o">.</span><span class="na">requireNonNull</span><span class="o">(</span><span class="nc">Objects</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">203</span><span class="o">)</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">dovydasvenckus</span><span class="o">.</span><span class="na">lambda</span><span class="o">.</span><span class="na">Main</span><span class="o">.</span><span class="na">main</span><span class="o">(</span><span class="nc">Main</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">14</span><span class="o">)</span></code></pre></figure>
<h2 id="summary">Summary</h2>
<p>An object must be initialized before using method reference operator on it.</p>
<p>Lambdas are bit different, they can access a variable from outside their scope.</p>Dovydas VenckusMost of the IDE’s give you hints, that you could replace lambdas with method references. But there is a subtle difference between them.Hello world!2016-10-19T19:07:59+00:002016-10-19T19:07:59+00:00https://www.dovydasvenckus.dev/update/2016/10/19/hello-world<p>I always planned to run my own tech blog. It’s funny how long it took me to get started.</p>
<p>An idea about tech blog probably came on the second year at university around 2013.
Instead of using WordPress or another blogging engine I have started developing blog application using Spring in early 2014.
I had no experience in building web applications. So this project was good learning opportunity.
After 4-5 months I had a somewhat functioning prototype. But this application hasn’t reached daylight.</p>
<p>A Year later in 2015 July I have started writing next iteration of my blogging application.
This time I have chosen Grails for backend and Angular for front end. This time my vision was bolder.
I tried to include many unnecessary bells and whistles in simple blogging application.
I even tried to implement a notification system that would send XMPP message, when somebody posted a comment on my blog.
After 6 months I had a working version, but again it has not reached daylight.
At least I have gained some experience working with more modern JS libraries.</p>
<p>There was an even third iteration of blogging application. In the, middle of 2016 I have started playing with spring boot.
So I had idea to rewrite my second version from Grails 3 to spring boot, because Grails seemed too heavyweight for simple application.
I’m happy that I haven’t got that far with it. I have only made couple commits.</p>
<p>Here I am more than 3 years later, with couple blogging application prototypes and without a single blog post. Funny, isn’t it?</p>
<p>This time I chose Jekyll instead of writing 4th iteration of blogging application.
I like Jekyll because of its simplicity and transparency.</p>
<p>In this blog, I’ll try to share what I’m working on and what I have learned recently.</p>Dovydas VenckusI always planned to run my own tech blog. It’s funny how long it took me to get started.