tag:blogger.com,1999:blog-74095974080230817122024-03-22T16:42:52.709+01:00Random Thoughts on Java ProgrammingTrying to define some of my thoughts on Software Design.Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.comBlogger495125tag:blogger.com,1999:blog-7409597408023081712.post-29135114492961071422024-02-23T16:02:00.003+01:002024-02-26T11:17:21.838+01:00Migrating Oracle to PostgreSQL<p>So at work we're currently trying to see if we can move away from Oracle and onto PostgreSQL.</p>
<p>I expect this to be a long process.</p>
<p>This blog post is here to document some of the issues we ran into and also remember references I found.</p>
<h1>Migrating schema and data</h1>
<p>There are several tools that can migrate the schema and the data from Oracle to Postgres.</p>
<p>There are some differences in what both database support. See reference [1].</p>
<h1>Make changes to SQL Scripts</h1>
<h1>References</h1>
<dl>
<dt>[1] Hackermoon - How to Migrate from Oracle to PostgreSQL</dt><dd><a href="https://hackernoon.com/how-to-migrate-from-oracle-to-postgresql">https://hackernoon.com/how-to-migrate-from-oracle-to-postgresql</a></dd>
<dt>Postgres Wiki - Oracle to Postgres Conversion</dt><dd><a href="https://wiki.postgresql.org/wiki/Oracle_to_Postgres_Conversion">https://wiki.postgresql.org/wiki/Oracle_to_Postgres_Conversion</a></dd>
<dt>PostgreSQL Manuals</dt><dd><a href="https://www.postgresql.org/docs/">https://www.postgresql.org/docs/</a></dd>
<dt>Ora2Pg - Moves Oracle and MySQL database to PostgreSQL</dt><dd><a href="https://ora2pg.darold.net/">https://ora2pg.darold.net/</a></dd>
<dt>Life in USA - install ora2pg on mac osx</dt><dd><a href="https://vcfvct.wordpress.com/2016/10/18/install-ora2pg-on-mac-osx/">https://vcfvct.wordpress.com/2016/10/18/install-ora2pg-on-mac-osx/</a></dd>
</dl>Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-25221891509339518582024-01-12T11:35:00.004+01:002024-02-02T10:34:38.628+01:00SQL: Concat operator and Spaces<p>So I had a pressing need to query my database and concatenate several values from a row together (using either concat or ||), but with spaces in between.</p>
<p>But I don't want two spaces if the value in between is empty.</p>
<p>It is surprisingly difficult to do in SQL, but there are some options available.</p>
<p>First the data:</p>
<table>
<tr><th>TITLE</th><th>FIRSTNAME</th><th>MIDDLENAME</th><th>FAMILYNAME</th></tr>
<tr><td></td><td>Ichabod</td><td></td><td>Crane</td></tr>
<tr><td>Dr.</td><td>Thomas</td><td></td><td>Lancaster</td></tr>
<tr><td></td><td>Philip</td><td>Martin</td><td>Brown</td></tr>
</table>
<h3>0. No solution</h3>
<div class="code">select TITLE || ' ' || FIRSTNAME || ' ' || MIDDLENAME || ' ' || FAMILYNAME from PERSON;</div>
<p>So, if you use the SQL statement above, you get the problem, extraneous spaces. For example "[ ]Ichabod[ ][ ]Crane". We wish to eliminate those.</p>
<h3>1. COALESCE</h3>
<div class="code">select coalesce(TITLE || ' ','') || coalesce(FIRSTNAME || ' ','') || coalesce(MIDDLENAME || ' ','') || FAMILYNAME from PERSON;</div>
<p>This is a good try, but doesn't work, as the first expression of the coalesce is never NULL, because of the concat used with the space (|| ' ') used.</p>
<h3>1. DECODE</h3>
<div class="code">
select decode(TITLE, null, '', TITLE, TITLE || ' ') ||<br/>
decode(FIRSTNAME, null, '', FIRSTNAME, FIRSTNAME || ' ') ||<br/>
decode(MIDDLENAME, null, '', MIDDLENAME, MIDDLENAME || ' ') ||<br/>
FAMILYNAME<br/>
from PERSON;</div>
<p>This works but is a lot of code to do something very simple.</p>
<h3>2. CASE</h3>
<div class="code">select (case<br/>
when TITLE is null then ''<br/>
else TITLE || ' ' end) ||<br/>
(case<br/>
when FIRSTNAME is null then ''<br/>
else FIRSTNAME || ' ' end) ||<br/>
(case<br/>
when MIDDLENAME is null then ''<br/>
else MIDDLENAME || ' ' end) ||<br/>
FAMILYNAME<br/>
from PERSON;</div>
<p>This works but is a lot of code. Luckily the case statement, when indented properly, is quite readable and not at all bad.</p>
<h3>3. NVL2</h3>
<div class="code">select nvl2(TITLE, TITLE || ' ', '') ||<br/>
nvl2(FIRSTNAME, FIRSTNAME || ' ', '') ||<br/>
nvl2(MIDDLENAME, MIDDLENAME || ' ', '') ||<br/>
FAMILYNAME from PERSON;</div>
<p>This works but is hard to read. Requires knowledge of nvl2.</p>
<h3>4. LTRIM</h3>
<div class="code">select ltrim(TITLE || ' ') ||<br/>
ltrim(FIRSTNAME || ' ') ||<br/>
ltrim(MIDDLENAME || ' ') ||<br/>
FAMILYNAME from PERSON;</div>
<p>As far as I can tell, this is quite appropriate. The ltrim removes spaces at the beginning of the string. If the string contains only ' ', all ' ' are removed and we're home free.</p>
<p>It is short, but requires some knowledge of what ltrim does exactly.</p>
<p>Falls in the category of 'doing something clever'.</p>
<h3>5. REGEXP_REPLACE</h3>
<div class="code">select regexp_replace(TITLE<br/>
|| ' ' || FIRSTNAME<br/>
|| ' ' || MIDDLENAME<br/>
|| ' ' || FAMILYNAME<br/>
, ' +', ' ')<br/>
from person;
</div>
<p>A colleague of mine came up with this little chestnut.</p>
<p>It's nice if you enjoy regular expressions. I do not.</p>
<p>Still, it's nice to be able to just concat everything together, and have the whole thing sorted out with one simple regular expression.</p>
<h3>Addendum</h3>
<p>The function wm_concat has been removed from Oracle PL/SQL and should not be used.</p>
<p>Which is a shame, as it does exactly what we want.</p>
<h1>References</h1>
<dl>
<dt>American Culture - Naming</dt><dd><a href="https://culturalatlas.sbs.com.au/american-culture/american-culture-naming">https://culturalatlas.sbs.com.au/american-culture/american-culture-naming</a></dd>
<dt>Lalit Kumar B - Why not use WM_CONCAT function in Oracle?</dt>
<dd><a href="https://lalitkumarb.wordpress.com/2015/04/29/why-not-use-wm_concat-function-in-oracle/">https://lalitkumarb.wordpress.com/2015/04/29/why-not-use-wm_concat-function-in-oracle/</a></dd>
</dl>
<p>Updates: added regexp_replace solution</p>Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-58665121932392049602023-12-29T11:00:00.001+01:002023-12-29T11:01:30.138+01:00The DUAL table<p>I'm working with Oracle databases (version 19 for now), and I always wondered about the weird DUAL table<sup>1</sup> that I require in my work.</p>
<p>Things like this:</p>
<div class="code">
select sysdate from dual;<br>
select seq_s_ordertable.nextval from dual;</div>
<p>Well, apparently we have Charles "Chuck" Weiss<sup>2</sup> to thank for it.</p>
<p>One of the reasons is that the FROM clause in Oracle SQL syntax is mandatory.</p>
<p>Interestingly, Charles originally created the DUAL table with two rows, hence the name DUAL. Nowadays it's one row, but the name's stuck.</p>
<p>It's part of the Data Dictionary of the SYS user. Changing the DUAL table will cause problems!<sup>3</sup></p>
<h1>References</h1>
<dl>
<dt>[1] Wikipedia - DUAL table</dt><dd><a href="https://en.wikipedia.org/wiki/DUAL_table">https://en.wikipedia.org/wiki/DUAL_table</a></dd>
<dt>[2] Wikipedia - Charles Weiss</dt><dd><a href="https://en.wikipedia.org/wiki/Charles_Weiss">https://en.wikipedia.org/wiki/Charles_Weiss</a></dd>
<dt>[3] Ask tom - All about the DUAL table</dt><dd><a href="https://asktom.oracle.com/ords/f?p=100:11:0::::P11_QUESTION_ID:1562813956388">https://asktom.oracle.com/ords/f?p=100:11:0::::P11_QUESTION_ID:1562813956388</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-2018395432262030832023-12-21T17:14:00.001+01:002023-12-21T17:14:00.141+01:00Using Java to Zip/Unzip files<p>There's been a ZipFile class in Java sinds a long time. But nowadays sinds JDK7 there's also a ZipFileSystem which is a bit easier to work with in some cases and can do more things.</p>
<p>Below are two examples, one using ZipFile and one using ZipFileSystem.</p>
<h2>Using ZipFile</h2>
<p>Unzipping works as follows:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #555555; font-weight: bold">@Test</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">testOldZip</span><span style="color: #333333">()</span> <span style="color: #008800; font-weight: bold">throws</span> URISyntaxException<span style="color: #333333">,</span> IOException <span style="color: #333333">{</span>
URL resource <span style="color: #333333">=</span> UnzipperTest<span style="color: #333333">.</span><span style="color: #0000CC">class</span><span style="color: #333333">.</span><span style="color: #0000CC">getResource</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"/test.zip"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">assert</span> resource <span style="color: #333333">!=</span> <span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">;</span>
Path path <span style="color: #333333">=</span> Path<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span>resource<span style="color: #333333">.</span><span style="color: #0000CC">toURI</span><span style="color: #333333">());</span>
<span style="color: #008800; font-weight: bold">try</span> <span style="color: #333333">(</span>var zipFile <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ZipFile<span style="color: #333333">(</span>path<span style="color: #333333">.</span><span style="color: #0000CC">toFile</span><span style="color: #333333">()))</span> <span style="color: #333333">{</span>
Enumeration<span style="color: #333333"><?</span> <span style="color: #008800; font-weight: bold">extends</span> ZipEntry<span style="color: #333333">></span> entries <span style="color: #333333">=</span> zipFile<span style="color: #333333">.</span><span style="color: #0000CC">entries</span><span style="color: #333333">();</span>
<span style="color: #008800; font-weight: bold">while</span> <span style="color: #333333">(</span>entries<span style="color: #333333">.</span><span style="color: #0000CC">hasMoreElements</span><span style="color: #333333">())</span> <span style="color: #333333">{</span>
ZipEntry nextElement <span style="color: #333333">=</span> entries<span style="color: #333333">.</span><span style="color: #0000CC">nextElement</span><span style="color: #333333">();</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>nextElement<span style="color: #333333">.</span><span style="color: #0000CC">isDirectory</span><span style="color: #333333">())</span> <span style="color: #333333">{</span>
log<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"File "</span> <span style="color: #333333">+</span> nextElement<span style="color: #333333">.</span><span style="color: #0000CC">getName</span><span style="color: #333333">()</span> <span style="color: #333333">+</span> <span style="background-color: #fff0f0">" from zipfile is a directory - skipped"</span><span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">else</span> <span style="color: #0066BB; font-weight: bold">if</span> <span style="color: #333333">(</span>nextElement<span style="color: #333333">.</span><span style="color: #0000CC">getName</span><span style="color: #333333">().</span><span style="color: #0000CC">contains</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"__MACOSX"</span><span style="color: #333333">))</span> <span style="color: #333333">{</span>
log<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"File "</span> <span style="color: #333333">+</span> nextElement<span style="color: #333333">.</span><span style="color: #0000CC">getName</span><span style="color: #333333">()</span> <span style="color: #333333">+</span> <span style="background-color: #fff0f0">" from zipfile is a MACOS file/dir - skipped"</span><span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">else</span> <span style="color: #333333">{</span>
log<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"File "</span> <span style="color: #333333">+</span> nextElement<span style="color: #333333">.</span><span style="color: #0000CC">getName</span><span style="color: #333333">()</span> <span style="color: #333333">+</span> <span style="background-color: #fff0f0">" retrieved from zip."</span><span style="color: #333333">);</span>
var filename <span style="color: #333333">=</span> nextElement<span style="color: #333333">.</span><span style="color: #0000CC">getName</span><span style="color: #333333">();</span>
InputStream inputStream <span style="color: #333333">=</span> zipFile<span style="color: #333333">.</span><span style="color: #0000CC">getInputStream</span><span style="color: #333333">(</span>nextElement<span style="color: #333333">);</span>
result<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">new</span> FileContents<span style="color: #333333">(</span>filename<span style="color: #333333">,</span> inputStream<span style="color: #333333">.</span><span style="color: #0000CC">readAllBytes</span><span style="color: #333333">()));</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
assertThat<span style="color: #333333">(</span>result<span style="color: #333333">).</span><span style="color: #0000CC">hasSize</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">6</span><span style="color: #333333">);</span>
assertThat<span style="color: #333333">(</span>result<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">().</span><span style="color: #0000CC">map</span><span style="color: #333333">(</span>x <span style="color: #333333">-></span> x<span style="color: #333333">.</span><span style="color: #0000CC">filename</span><span style="color: #333333">).</span><span style="color: #0000CC">collect</span><span style="color: #333333">(</span>Collectors<span style="color: #333333">.</span><span style="color: #0000CC">toList</span><span style="color: #333333">())).</span><span style="color: #0000CC">isEqualTo</span><span style="color: #333333">(</span>
List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"test/test1.txt"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"test/test/ziptest.zip"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"test/test/ziptest/zippem2.txt"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"test/test/ziptest/zippem.txt"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"test/test2/test2.txt"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"test/test2/text3.xml"</span><span style="color: #333333">));</span>
assertThat<span style="color: #333333">(</span>log<span style="color: #333333">).</span><span style="color: #0000CC">hasSize</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">11</span><span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">isEqualTo</span><span style="color: #333333">(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"File test/ from zipfile is a directory - skipped"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test1.txt retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test/ from zipfile is a directory - skipped"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test/ziptest.zip retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test/ziptest/ from zipfile is a directory - skipped"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test/ziptest/zippem2.txt retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test/ziptest/zippem.txt retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test2/ from zipfile is a directory - skipped"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test2/test2.txt retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test2/test3/ from zipfile is a directory - skipped"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File test/test2/text3.xml retrieved from zip."</span><span style="color: #333333">));</span>
<span style="color: #333333">}</span>
</pre></div>
<h2>Using ZipFileSystem</h2>
<p>Apparently it is also possible to mount a zip file as a FileSystem (sinds JDK 7).</p>
<p>It's a bit easier to work with, and has less problems with leaking resources/streams, and allows easy editing and removing items from the zip.</p>
<p>On the other hand, some FileSystem operations are not available in a ZipFileSystem, and then you get a UnsupportedOperationException.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #008800; font-weight: bold">private</span> <span style="color: #008800; font-weight: bold">static</span> <span style="color: #008800; font-weight: bold">class</span> <span style="color: #BB0066; font-weight: bold">ZipVisitor</span>
<span style="color: #008800; font-weight: bold">extends</span> SimpleFileVisitor<span style="color: #333333"><</span>Path<span style="color: #333333">></span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">private</span> <span style="color: #008800; font-weight: bold">final</span> List<span style="color: #333333"><</span>FileContents<span style="color: #333333">></span> result<span style="color: #333333">;</span>
<span style="color: #008800; font-weight: bold">private</span> <span style="color: #008800; font-weight: bold">final</span> List<span style="color: #333333"><</span>String<span style="color: #333333">></span> log<span style="color: #333333">;</span>
<span style="color: #008800; font-weight: bold">private</span> <span style="color: #0066BB; font-weight: bold">ZipVisitor</span><span style="color: #333333">(</span>List<span style="color: #333333"><</span>FileContents<span style="color: #333333">></span> result<span style="color: #333333">,</span> List<span style="color: #333333"><</span>String<span style="color: #333333">></span> log<span style="color: #333333">)</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">this</span><span style="color: #333333">.</span><span style="color: #0000CC">result</span> <span style="color: #333333">=</span> result<span style="color: #333333">;</span>
<span style="color: #008800; font-weight: bold">this</span><span style="color: #333333">.</span><span style="color: #0000CC">log</span> <span style="color: #333333">=</span> log<span style="color: #333333">;</span>
<span style="color: #333333">}</span>
<span style="color: #555555; font-weight: bold">@Override</span>
<span style="color: #008800; font-weight: bold">public</span> FileVisitResult <span style="color: #0066BB; font-weight: bold">visitFile</span><span style="color: #333333">(</span>Path file<span style="color: #333333">,</span> BasicFileAttributes attrs<span style="color: #333333">)</span> <span style="color: #008800; font-weight: bold">throws</span> IOException <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>file<span style="color: #333333">.</span><span style="color: #0000CC">toString</span><span style="color: #333333">().</span><span style="color: #0000CC">contains</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"__MACOSX"</span><span style="color: #333333">))</span> <span style="color: #333333">{</span>
log<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"File "</span> <span style="color: #333333">+</span> file <span style="color: #333333">+</span> <span style="background-color: #fff0f0">" from zipfile is a MACOS file/dir - skipped"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> FileVisitResult<span style="color: #333333">.</span><span style="color: #0000CC">CONTINUE</span><span style="color: #333333">;</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>file<span style="color: #333333">.</span><span style="color: #0000CC">toString</span><span style="color: #333333">(),</span> <span style="background-color: #fff0f0">".DS_Store"</span><span style="color: #333333">))</span> <span style="color: #333333">{</span>
log<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"File "</span> <span style="color: #333333">+</span> file <span style="color: #333333">+</span> <span style="background-color: #fff0f0">" from zipfile is a .DS_Store file/dir - skipped"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> FileVisitResult<span style="color: #333333">.</span><span style="color: #0000CC">CONTINUE</span><span style="color: #333333">;</span>
<span style="color: #333333">}</span>
log<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"File "</span> <span style="color: #333333">+</span> file <span style="color: #333333">+</span> <span style="background-color: #fff0f0">" retrieved from zip."</span><span style="color: #333333">);</span>
String filename <span style="color: #333333">=</span> file<span style="color: #333333">.</span><span style="color: #0000CC">toString</span><span style="color: #333333">();</span>
<span style="color: #888888">// file.toFile() -> unsupported operation.</span>
result<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">new</span> FileContents<span style="color: #333333">(</span>filename<span style="color: #333333">,</span> Files<span style="color: #333333">.</span><span style="color: #0000CC">readAllBytes</span><span style="color: #333333">(</span>file<span style="color: #333333">)));</span>
<span style="color: #008800; font-weight: bold">return</span> FileVisitResult<span style="color: #333333">.</span><span style="color: #0000CC">CONTINUE</span><span style="color: #333333">;</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #555555; font-weight: bold">@Test</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">testNewZip</span><span style="color: #333333">()</span> <span style="color: #008800; font-weight: bold">throws</span> URISyntaxException<span style="color: #333333">,</span> IOException <span style="color: #333333">{</span>
URL resource <span style="color: #333333">=</span> UnzipperTest<span style="color: #333333">.</span><span style="color: #0000CC">class</span><span style="color: #333333">.</span><span style="color: #0000CC">getResource</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"/test.zip"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">assert</span> resource <span style="color: #333333">!=</span> <span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">;</span>
var path <span style="color: #333333">=</span> Path<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span>resource<span style="color: #333333">.</span><span style="color: #0000CC">toURI</span><span style="color: #333333">());</span>
<span style="color: #008800; font-weight: bold">try</span> <span style="color: #333333">(</span>FileSystem filesystem <span style="color: #333333">=</span> FileSystems<span style="color: #333333">.</span><span style="color: #0000CC">newFileSystem</span><span style="color: #333333">(</span>path<span style="color: #333333">,</span> Collections<span style="color: #333333">.</span><span style="color: #0000CC">emptyMap</span><span style="color: #333333">()))</span> <span style="color: #333333">{</span>
var rootDirectories <span style="color: #333333">=</span> filesystem<span style="color: #333333">.</span><span style="color: #0000CC">getRootDirectories</span><span style="color: #333333">();</span>
rootDirectories<span style="color: #333333">.</span><span style="color: #0000CC">forEach</span><span style="color: #333333">(</span>root <span style="color: #333333">-></span>
<span style="color: #888888">//walk the zip file tree</span>
<span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">try</span> <span style="color: #333333">{</span>
Files<span style="color: #333333">.</span><span style="color: #0000CC">walkFileTree</span><span style="color: #333333">(</span>root<span style="color: #333333">,</span> <span style="color: #008800; font-weight: bold">new</span> ZipVisitor<span style="color: #333333">(</span>result<span style="color: #333333">,</span> log<span style="color: #333333">));</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">catch</span> <span style="color: #333333">(</span>IOException e<span style="color: #333333">)</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">throw</span> <span style="color: #008800; font-weight: bold">new</span> <span style="color: #0066BB; font-weight: bold">RuntimeException</span><span style="color: #333333">(</span>e<span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #333333">);</span>
<span style="color: #333333">}</span>
assertThat<span style="color: #333333">(</span>result<span style="color: #333333">).</span><span style="color: #0000CC">hasSize</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">6</span><span style="color: #333333">);</span>
assertThat<span style="color: #333333">(</span>result<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">().</span><span style="color: #0000CC">map</span><span style="color: #333333">(</span>x <span style="color: #333333">-></span> x<span style="color: #333333">.</span><span style="color: #0000CC">filename</span><span style="color: #333333">).</span><span style="color: #0000CC">collect</span><span style="color: #333333">(</span>Collectors<span style="color: #333333">.</span><span style="color: #0000CC">toList</span><span style="color: #333333">())).</span><span style="color: #0000CC">isEqualTo</span><span style="color: #333333">(</span>
List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"/test/test2/text3.xml"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"/test/test2/test2.txt"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"/test/test/ziptest/zippem.txt"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"/test/test/ziptest/zippem2.txt"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"/test/test/ziptest.zip"</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"/test/test1.txt"</span><span style="color: #333333">));</span>
assertThat<span style="color: #333333">(</span>log<span style="color: #333333">).</span><span style="color: #0000CC">hasSize</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">6</span><span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">isEqualTo</span><span style="color: #333333">(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"File /test/test2/text3.xml retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File /test/test2/test2.txt retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File /test/test/ziptest/zippem.txt retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File /test/test/ziptest/zippem2.txt retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File /test/test/ziptest.zip retrieved from zip."</span><span style="color: #333333">,</span>
<span style="background-color: #fff0f0">"File /test/test1.txt retrieved from zip."</span><span style="color: #333333">));</span>
<span style="color: #333333">}</span>
</pre></div>
<h1>References</h1>
<dl>
<dt>fahd.blog - Java 7: Working with Zip Files</dt>
<dd><a href="https://fahdshariff.blogspot.com/2011/08/java-7-working-with-zip-files.html">https://fahdshariff.blogspot.com/2011/08/java-7-working-with-zip-files.html</a></dd>
<dt>Oracle Java Documentation - Zip File System Provider</dt>
<dd><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/io/fsp/zipfilesystemprovider.html">https://docs.oracle.com/javase/8/docs/technotes/guides/io/fsp/zipfilesystemprovider.html</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-61753595104083710162023-12-14T14:21:00.003+01:002023-12-14T14:21:00.148+01:00Streams and Filters<p>A simple little thing.</p>
<p>I like to use streams and filters, and I was wondering what's the best way to go about some things.</p>
<p>For example: I wish to search for a person in a list of Persons.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #555555; font-weight: bold">@Test</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">testSimple</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
Person personToFind <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Mr."</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Bear"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Netherlands"</span><span style="color: #333333">);</span>
Person otherPersonToFind <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Linda"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Lovelace"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"England"</span><span style="color: #333333">);</span>
assertThat<span style="color: #333333">(</span>Persons<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>personToFind<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">())</span> <span style="color: #333333">&&</span>
Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>personToFind<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">())</span> <span style="color: #333333">&&</span>
Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>personToFind<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">()))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">()).</span><span style="color: #0000CC">isPresent</span><span style="color: #333333">();</span>
assertThat<span style="color: #333333">(</span>Persons<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>otherPersonToFind<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">())</span> <span style="color: #333333">&&</span>
Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>otherPersonToFind<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">())</span> <span style="color: #333333">&&</span>
Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>otherPersonToFind<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">()))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">()).</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">();</span>
<span style="color: #333333">}</span>
</pre></div>
<p>This works, but the single filter with all the && in it seems a bit unreadable.</p>
<p>Of course, I could replace the x&&y&&z by three filters, as it boils down tot the same thing.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #555555; font-weight: bold">@Test</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">testSimple2</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
Person personToFind <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Mr."</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Bear"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Netherlands"</span><span style="color: #333333">);</span>
Person otherPersonToFind <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Linda"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Lovelace"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"England"</span><span style="color: #333333">);</span>
assertThat<span style="color: #333333">(</span>Persons<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>personToFind<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">()))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>personToFind<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">()))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>personToFind<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">()))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">()).</span><span style="color: #0000CC">isPresent</span><span style="color: #333333">();</span>
assertThat<span style="color: #333333">(</span>Persons<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>otherPersonToFind<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">()))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>otherPersonToFind<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">()))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>otherPersonToFind<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">()))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">()).</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">();</span>
<span style="color: #333333">}</span>
</pre></div>
<p>But my colleague always likes to use specific methods for lambdas, even if they're only a little complex. It just reads easier.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">private</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">compare</span><span style="color: #333333">(</span>Person person<span style="color: #333333">,</span> Person otherPerson<span style="color: #333333">)</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">return</span> Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>otherPerson<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">name</span><span style="color: #333333">())</span> <span style="color: #333333">&&</span>
Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>otherPerson<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">surname</span><span style="color: #333333">())</span> <span style="color: #333333">&&</span>
Objects<span style="color: #333333">.</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>otherPerson<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">(),</span> person<span style="color: #333333">.</span><span style="color: #0000CC">country</span><span style="color: #333333">());</span>
<span style="color: #333333">}</span>
<span style="color: #555555; font-weight: bold">@Test</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">testSimple3</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
Person personToFind <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Mr."</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Bear"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Netherlands"</span><span style="color: #333333">);</span>
Person otherPersonToFind <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Linda"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Lovelace"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"England"</span><span style="color: #333333">);</span>
assertThat<span style="color: #333333">(</span>Persons<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> compare<span style="color: #333333">(</span>person<span style="color: #333333">,</span> personToFind<span style="color: #333333">))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">()).</span><span style="color: #0000CC">isPresent</span><span style="color: #333333">();</span>
assertThat<span style="color: #333333">(</span>Persons<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> compare<span style="color: #333333">(</span>person<span style="color: #333333">,</span> otherPersonToFind<span style="color: #333333">))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">()).</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">();</span>
<span style="color: #333333">}</span>
</pre></div>
<p>My personal preference is the last one.</p>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-40620936886837805102023-12-07T11:26:00.001+01:002023-12-07T11:26:00.144+01:00Is Stream.findFirst() Short-circuited?<p>So, the assumption is: if I use findFirst on a stream, none of the items in the stream after the first match are evaluated.</p>
<p>I assumed that it was, and it is, but it's always nice to see this verified in a simple test.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #008800; font-weight: bold">private</span> List<span style="color: #333333"><</span>String<span style="color: #333333">></span> list <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>();</span>
<span style="color: #008800; font-weight: bold">private</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">add</span><span style="color: #333333">(</span>String message<span style="color: #333333">,</span> <span style="color: #333399; font-weight: bold">boolean</span> returnValue<span style="color: #333333">)</span> <span style="color: #333333">{</span>
list<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span>message<span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> returnValue<span style="color: #333333">;</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">check</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
List<span style="color: #333333"><</span>Supplier<span style="color: #333333"><</span>Boolean<span style="color: #333333">>></span> checks <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>();</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">super</span><span style="color: #333333">::</span>onLeave<span style="color: #333333">);</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(()</span> <span style="color: #333333">-></span> <span style="color: #333333">{</span>
list<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"First expression"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">true</span><span style="color: #333333">;</span>
<span style="color: #333333">});</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(()</span> <span style="color: #333333">-></span> <span style="color: #333333">{</span>
list<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"Second expression"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">true</span><span style="color: #333333">;</span>
<span style="color: #333333">});</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(()</span> <span style="color: #333333">-></span> <span style="color: #333333">{</span>
list<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"Third expression"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">false</span><span style="color: #333333">;</span>
<span style="color: #333333">});</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(()</span> <span style="color: #333333">-></span> <span style="color: #333333">{</span>
list<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"Fourth expression"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">true</span><span style="color: #333333">;</span>
<span style="color: #333333">});</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(()</span> <span style="color: #333333">-></span> <span style="color: #333333">{</span>
list<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"Fifth expression"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">true</span><span style="color: #333333">;</span>
<span style="color: #333333">});</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(()</span> <span style="color: #333333">-></span> <span style="color: #333333">{</span>
list<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"Sixth expression"</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">false</span><span style="color: #333333">;</span>
<span style="color: #333333">});</span>
<span style="color: #008800; font-weight: bold">return</span> checks<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>t <span style="color: #333333">-></span> t<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>Boolean<span style="color: #333333">.</span><span style="color: #0000CC">FALSE</span><span style="color: #333333">))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">();</span>
<span style="color: #333333">}</span>
<span style="color: #555555; font-weight: bold">@Test</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">testShortCircuit</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
assertThat<span style="color: #333333">(</span>check<span style="color: #333333">()).</span><span style="color: #0000CC">isFalse</span><span style="color: #333333">();</span>
assertThat<span style="color: #333333">(</span>list<span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">containsExactly</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"First expression"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Second expression"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Third expression"</span><span style="color: #333333">);</span>
<span style="color: #333333">}</span>
</pre></div>
<p>As this test passes, it seems that way.</p>
<p>In the very beginning it took some time for me to wrap my head around it, but the operations you define on a stream (.map, .filter, etc.) are not all processed on every item in the stream.</p>
<p>All operations are processed on the first item of the stream, then on the second item of the stream. From this it follows, that a .findFirst() operation will immediately terminate operations if it finds one and the rest of the stream will be ignored.</p>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-34214080248887432202023-11-30T08:22:00.003+01:002023-11-30T08:22:00.262+01:00Refactoring<p>So, I saw some code that I didn't like, and I decided to refactor it.</p>
<p>The code was thusly.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">onLeave</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
<span style="color: #333399; font-weight: bold">boolean</span> valid <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">super</span><span style="color: #333333">.</span><span style="color: #0000CC">onLeave</span><span style="color: #333333">();</span>
Account account <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getAccount</span><span style="color: #333333">();</span>
ShoppingList shoppingList <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getShoppinglist</span><span style="color: #333333">(</span>account<span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>valid<span style="color: #333333">)</span> <span style="color: #333333">{</span>
valid <span style="color: #333333">=</span> <span style="color: #333333">!</span>shoppingList<span style="color: #333333">.</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">();</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>valid<span style="color: #333333">)</span> <span style="color: #333333">{</span>
valid <span style="color: #333333">=</span> <span style="color: #333333">!</span>blockedAccounts<span style="color: #333333">.</span><span style="color: #0000CC">contains</span><span style="color: #333333">(</span>account<span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>valid<span style="color: #333333">)</span> <span style="color: #333333">{</span>
String country <span style="color: #333333">=</span> account<span style="color: #333333">.</span><span style="color: #0000CC">getPerson</span><span style="color: #333333">().</span><span style="color: #0000CC">country</span><span style="color: #333333">();</span>
valid <span style="color: #333333">=</span> webshop<span style="color: #333333">.</span><span style="color: #0000CC">alsoShipsTo</span><span style="color: #333333">(</span>country<span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>valid<span style="color: #333333">)</span> <span style="color: #333333">{</span>
valid <span style="color: #333333">=</span> account<span style="color: #333333">.</span><span style="color: #0000CC">hasCreditcardAttached</span><span style="color: #333333">()</span> <span style="color: #333333">||</span>
account<span style="color: #333333">.</span><span style="color: #0000CC">hasPrepaidcardAttached</span><span style="color: #333333">()</span> <span style="color: #333333">||</span>
account<span style="color: #333333">.</span><span style="color: #0000CC">hasCash</span><span style="color: #333333">();</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">return</span> valid<span style="color: #333333">;</span>
<span style="color: #333333">}</span>
</pre></div>
<p>And I thought to myself, it's really just a list of expressions, where each one is evaluated until you find one that evaluates to false, and then you stop.</p>
<p>So, that's basically a Stream where you filter out all the "false" values, and get the first one.</p>
<p>So, I decided to refactor it just like that.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">onLeave</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
Account account <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getAccount</span><span style="color: #333333">();</span>
ShoppingList shoppingList <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getShoppinglist</span><span style="color: #333333">(</span>account<span style="color: #333333">);</span>
List<span style="color: #333333"><</span>Supplier<span style="color: #333333"><</span>Boolean<span style="color: #333333">>></span> checks <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>();</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">super</span><span style="color: #333333">::</span>onLeave<span style="color: #333333">);</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(()</span> <span style="color: #333333">-></span> <span style="color: #333333">!</span>shoppingList<span style="color: #333333">.</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">());</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(()</span> <span style="color: #333333">-></span> <span style="color: #333333">!</span>blockedAccounts<span style="color: #333333">.</span><span style="color: #0000CC">contains</span><span style="color: #333333">(</span>account<span style="color: #333333">));</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span>
<span style="color: #333333">()</span> <span style="color: #333333">-></span> <span style="color: #333333">{</span>
String country <span style="color: #333333">=</span> account<span style="color: #333333">.</span><span style="color: #0000CC">getPerson</span><span style="color: #333333">().</span><span style="color: #0000CC">country</span><span style="color: #333333">();</span>
<span style="color: #008800; font-weight: bold">return</span> webshop<span style="color: #333333">.</span><span style="color: #0000CC">alsoShipsTo</span><span style="color: #333333">(</span>country<span style="color: #333333">);</span>
<span style="color: #333333">});</span>
checks<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(()</span> <span style="color: #333333">-></span> account<span style="color: #333333">.</span><span style="color: #0000CC">hasCreditcardAttached</span><span style="color: #333333">()</span> <span style="color: #333333">||</span>
account<span style="color: #333333">.</span><span style="color: #0000CC">hasPrepaidcardAttached</span><span style="color: #333333">()</span> <span style="color: #333333">||</span>
account<span style="color: #333333">.</span><span style="color: #0000CC">hasCash</span><span style="color: #333333">());</span>
<span style="color: #008800; font-weight: bold">return</span> checks<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>t <span style="color: #333333">-></span> t<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>Boolean<span style="color: #333333">.</span><span style="color: #0000CC">FALSE</span><span style="color: #333333">))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">();</span>
<span style="color: #333333">}</span>
</pre></div>
<p>I proudly showed this to my colleagues, and they immediately shook their heads in disgust.</p>
<p>Apparently, in my eagerness to use Lambdas and Streams and all that cool stuff, what I really had done is recreated the short-circuit version of an If statement in Streams.</p>
<p>I find myself turning to Lambdas and Streams when in reality these are not needed, and my eventual solution works fine without them.</p>
<p>So, rewriting this as a short-circuited IF statement looks like this:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">onLeave</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
Account account <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getAccount</span><span style="color: #333333">();</span>
ShoppingList shoppingList <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getShoppinglist</span><span style="color: #333333">(</span>account<span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">super</span><span style="color: #333333">.</span><span style="color: #0000CC">onLeave</span><span style="color: #333333">()</span> <span style="color: #333333">&&</span>
<span style="color: #333333">!</span>shoppingList<span style="color: #333333">.</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">()</span> <span style="color: #333333">&&</span>
<span style="color: #333333">!</span>blockedAccounts<span style="color: #333333">.</span><span style="color: #0000CC">contains</span><span style="color: #333333">(</span>account<span style="color: #333333">)</span> <span style="color: #333333">&&</span>
webshop<span style="color: #333333">.</span><span style="color: #0000CC">alsoShipsTo</span><span style="color: #333333">(</span>account<span style="color: #333333">.</span><span style="color: #0000CC">getPerson</span><span style="color: #333333">().</span><span style="color: #0000CC">country</span><span style="color: #333333">())</span> <span style="color: #333333">&&</span>
<span style="color: #333333">(</span>account<span style="color: #333333">.</span><span style="color: #0000CC">hasCreditcardAttached</span><span style="color: #333333">()</span> <span style="color: #333333">||</span>
account<span style="color: #333333">.</span><span style="color: #0000CC">hasPrepaidcardAttached</span><span style="color: #333333">()</span> <span style="color: #333333">||</span>
account<span style="color: #333333">.</span><span style="color: #0000CC">hasCash</span><span style="color: #333333">());</span>
<span style="color: #333333">}</span>
</pre></div>
<p>Granted, a few more and my IntelliJ will start to complain about the number of expressions in the if statement, and it's possible to clean it up a little by creating separate methods for some of the expressions. But I feel it looks fine.</p>
<p>So, in conclusion, just because you know something cool and shiny, it's no reason to try and use it everywhere!</p>
<p>It is a corrolary that in order to properly use something, you must have some knowledge or experience of <i>when and where it's best to be used</i>.</p>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-78778888222059488112023-11-23T15:53:00.004+01:002023-11-23T15:53:00.147+01:00Is Java Pass-by-value or Pass-by-reference?<p>I thought I'd write a quick test to get things straight.</p>
<script src="https://gist.github.com/maartenl/b2bdeae5bd7d3c8cf60b998f47aea6e1.js"></script>Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-60825349142601358822023-11-16T16:45:00.000+01:002023-11-16T16:45:00.142+01:00Adding a device to a raid with mdadm<h1>Reordering partitions to make room</h1>
<p>So my current hard drives are:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"># lsscsi
[0:0:0:0] disk ATA Samsung SSD 860 1B6Q /dev/sda
[4:0:0:0] disk ATA WDC WD4003FZEX-0 1A01 /dev/sdb
[5:0:0:0] disk ATA WDC WD5000AAKS-0 3B01 /dev/sdc
[5:0:1:0] disk ATA ST2000DM001-1CH1 CC29 /dev/sdd
[10:0:0:0] disk WD Ext HDD 1021 2021 /dev/sde
[11:0:0:0] disk WD Ext HDD 1021 2021 /dev/sdf
</pre></div>
<p>I had a lot of unused space on /dev/sdb, and thought I could rearrange the partitions and use it as an additional device in my (software) RAID.</p>
<p>I used Parted<sup>1</sup>, but GParted<sup>2</sup> is also very nice. GParted can also scan my /dev/md127, which is a raid device.</p>
<p>Of course there's the general problem nowadays of looking what kind of MBR/GPT or whatever boot schema you use.</p>
<p>So:</p>
<div class="code">Disk /dev/sdb: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors<br/>
Disk model: WDC WD4003FZEX-0<br/>
Units: sectors of 1 * 512 = 512 bytes<br/>
Sector size (logical/physical): 512 bytes / 4096 bytes<br/>
I/O size (minimum/optimal): 4096 bytes / 4096 bytes<br/>
Disklabel type: gpt<br/>
Disk identifier: D344E388-FA66-4B30-BA00-4D3B12A07B79</div>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">Device Start End Sectors Size Type
/dev/sdb1 2048 4095 2048 1M BIOS boot
/dev/sdb2 4096 1028095 1024000 500M Linux filesystem
/dev/sdb3 1028096 5273437500 5272409405 2.5T Linux filesystem
/dev/sdb4 5273438208 7420921855 2147483648 1T Linux filesystem
</pre></div>
<p>So it's a 4 TB hard drive, and it turns out that I only use /dev/sdb3. (The other partitions are from an old Linux install before I got a nice SDD and reinstalled Linux/Windows on that.)</p>
<p>So I could first rearrange it: resize /dev/sdb3 to 2T and move it to /dev/sdb1.</p>
<p>That worked fine using Parted. It just took some time to actually move all the data.</p>
<p>And then create a new /dev/sdb2 of 2T for my raid with gdisk<sup>3</sup> (the GPT version of fdisk).</p>
<p>I had to look up the appropriate partition type in GPT<sup>4</sup> for mdadm.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">
# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.9
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): n
Partition number (2-128, default 2):
First sector (34-7814037134, default = 3907006464) or {+-}size{KMGTP}:
Last sector (3907006464-7814037134, default = 7814035455) or {+-}size{KMGTP}:
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): fd00
Changed type of partition to 'Linux RAID'
Command (? for help): p
Disk /dev/sdb: 7814037168 sectors, 3.6 TiB
Model: WDC WD4003FZEX-0
Sector size (logical/physical): 512/4096 bytes
Disk identifier (GUID): D344E388-FA66-4B30-BA00-4D3B12A07B79
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 7814037134
Partitions will be aligned on 2048-sector boundaries
Total free space is 3693 sectors (1.8 MiB)
Number Start (sector) End (sector) Size Code Name
1 2048 3907006463 1.8 TiB 8300
2 3907006464 7814035455 1.8 TiB FD00 Linux RAID
</pre></div>
<h1>Adding the device</h1>
<p>Current raid setup:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"># mdadm --assemble /dev/md127 /dev/sdd1 /dev/sde1 /dev/sdf1
mdadm: /dev/md127 has been started with 3 drives.
# mdadm --detail /dev/md127
/dev/md127:
Version : 1.2
Creation Time : Wed Mar 6 22:16:05 2013
Raid Level : raid1
Array Size : 1953380160 (1862.89 GiB 2000.26 GB)
Used Dev Size : 1953380160 (1862.89 GiB 2000.26 GB)
Raid Devices : 3
Total Devices : 3
Persistence : Superblock is persistent
Update Time : Wed Aug 16 09:08:07 2023
State : clean
Active Devices : 3
Working Devices : 3
Failed Devices : 0
Spare Devices : 0
Consistency Policy : resync
Name : micemouse:0
UUID : ed4531c4:59c132b2:a6bfc3d1:6da3b928
Events : 7285
Number Major Minor RaidDevice State
4 8 65 0 active sync /dev/sde1
5 8 81 1 active sync /dev/sdf1
3 8 49 2 active sync /dev/sdd1
</pre></div>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"># cat /proc/mdstat
Personalities : [raid1]
md127 : active raid1 sde1[4] sdd1[3] sdf1[5]
1953380160 blocks super 1.2 [3/3] [UUU]
unused devices: <none>
</pre></div>
<p>Adding a device:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">mdadm --add /dev/md127 /dev/sdb2
mdadm: added /dev/sdb2
md127 : active raid1 sdb2[6](S) sde1[4] sdd1[3] sdf1[5]
1953380160 blocks super 1.2 [3/3] [UUU]
unused devices: <none>
mdadm --detail /dev/md127
/dev/md127:
Version : 1.2
Creation Time : Wed Mar 6 22:16:05 2013
Raid Level : raid1
Array Size : 1953380160 (1862.89 GiB 2000.26 GB)
Used Dev Size : 1953380160 (1862.89 GiB 2000.26 GB)
Raid Devices : 3
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Sat Aug 19 16:47:58 2023
State : clean
Active Devices : 3
Working Devices : 4
Failed Devices : 0
Spare Devices : 1
Consistency Policy : resync
Name : micemouse:0
UUID : ed4531c4:59c132b2:a6bfc3d1:6da3b928
Events : 7286
Number Major Minor RaidDevice State
4 8 65 0 active sync /dev/sde1
5 8 81 1 active sync /dev/sdf1
3 8 49 2 active sync /dev/sdd1
6 8 18 - spare /dev/sdb2
</pre></div>
[<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">root@localhost ~]# mdadm --grow /dev/md127 --raid-devices=4
raid_disks for /dev/md127 set to 4
# mdadm --detail /dev/md127
/dev/md127:
Version : 1.2
Creation Time : Wed Mar 6 22:16:05 2013
Raid Level : raid1
Array Size : 1953380160 (1862.89 GiB 2000.26 GB)
Used Dev Size : 1953380160 (1862.89 GiB 2000.26 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Sat Aug 19 16:49:32 2023
State : clean, degraded, recovering
Active Devices : 3
Working Devices : 4
Failed Devices : 0
Spare Devices : 1
Consistency Policy : resync
Rebuild Status : 0% complete
Name : micemouse:0
UUID : ed4531c4:59c132b2:a6bfc3d1:6da3b928
Events : 7290
Number Major Minor RaidDevice State
4 8 65 0 active sync /dev/sde1
5 8 81 1 active sync /dev/sdf1
3 8 49 2 active sync /dev/sdd1
6 8 18 3 spare rebuilding /dev/sdb2
</pre></div>
<p>And now we wait.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"># cat /proc/mdstat
Personalities : [raid1]
md127 : active raid1 sdb2[6] sde1[4] sdd1[3] sdf1[5]
1953380160 blocks super 1.2 [4/3] [UUU_]
[>....................] recovery = 0.1% (2956032/1953380160) finish=1156.0min speed=28118K/sec
unused devices: <none>
</pre></div>
<p>Ready in about 12 hours.</p>
<h1>References</h1>
<dl>
<dt>[1] Parted User’s Manual</dt><dd><a href="https://www.gnu.org/software/parted/manual/parted.html">https://www.gnu.org/software/parted/manual/parted.html</a></dd>
<dt>[2] GParted is a free partition editor for graphically managing your disk partitions.</dt><dd><a href="https://gparted.org/">https://gparted.org/</a></dd>
<dt>[3] gdisk(8) - Linux man page</dt><dd><a href="https://linux.die.net/man/8/gdisk">https://linux.die.net/man/8/gdisk/</a></dd>
<dt>[4] Raid Wiki Kernel Org - Partition Types</dt><dd><a href="https://raid.wiki.kernel.org/index.php/Partition_Types">https://raid.wiki.kernel.org/index.php/Partition_Types</a></dd>
<dt>WP Guru - How to add a drive to software RAID with mdadm</dt><dd><a href="https://wpguru.co.uk/2021/01/expand-software-raid-mdadm/">https://wpguru.co.uk/2021/01/expand-software-raid-mdadm/</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-67728473332078713762023-11-09T12:05:00.000+01:002023-11-09T12:05:00.139+01:00The Java Playground<p>Apparently there's an official Java Playground on https://dev.java/.</p>
<p>They are working on using the Playground in your own webpages.</p>
<p>It is primarily created for developers to play around with the new Java, without having to install the new java.</p>
<p>But it's early and they have plans for it.</p>
<h1>References</h1>
<dl>
<dt>dev.java - The Java Playground</dt><dd><a href="https://dev.java/playground/">https://dev.java/playground/</a></dd>
<dt>dev.java</dt><dd><a href="https://dev.java/">https://dev.java/</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-38262429170299660532023-11-02T12:22:00.001+01:002023-11-02T12:22:00.152+01:00How to Change a Git Remote<p>I needed to change a remote, as the ip address of the remote server had changed.</p>
<div class="code">
$ git remote -v<br/>
origin ssh://mrbear@192.168.2.1:/home/mrbear/store (fetch)<br/>
origin ssh://mrbear@192.168.2.1:/home/mrbear/store (push)<br/></div>
<p>So to change it:</p>
<div class="code">
git remote set-url origin ssh://mrbear@192.168.2.7:/home/mrbear/store
</div>
<p>And it becomes:</p>
<div class="code">
$ git remote -v<br/>
origin ssh://mrbear@192.168.2.7:/home/mrbear/store (fetch)<br/>
origin ssh://mrbear@192.168.2.7:/home/mrbear/store (push)<br/></div>
<h1>References</h1>
<dl><dt>CareerKarma - How to Change a Git Remote</dt><dd><a href="https://careerkarma.com/blog/git-change-remote/">https://careerkarma.com/blog/git-change-remote/</a></dd></dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-37319290377082325332023-10-26T14:19:00.000+02:002023-10-26T14:19:00.162+02:00Trying my first JavaFX Program<p>So, I've looked up some websites on JavaFX as I wanted to quickly throw something nice together for drawing Geometry.</p>
<p>You can find my little tool on the GitHub<sup>1</sup>.</p>
<p>It works fine for what I needed. I wanted to be able to quickly show the difference between geometries.</p>
<p>The tool uses locationtech for geometry stuff, and javafx for display stuff.</p>
<p>It accepts WKT representations of geometry. Currently, these do not provide any coordinate systems, so you're unlucky there.</p>
<p>I did get the error:</p>
<div class="code">Error: JavaFX runtime components are missing, and are required to run this application</div>
<p>But I changed my app to pull JavaFX from Maven Central and that seems to fixed the issues. JavaFX is no longer included in any JDK.</p>
<h1>References</h1>
<dl>
<dt>[1] GitHub.com - geoviewer</dt><dd><a href="https://github.com/maartenl/geoviewer">https://github.com/maartenl/geoviewer</a></dd>
<dt>JavaFX - Getting Started with JavaFX</dt><dd><a href="https://openjfx.io/openjfx-docs/#maven">https://openjfx.io/openjfx-docs/#maven</a> </dd>
<dt>developer.com - Using Graphics in JavaFX</dt><dd><a href="https://www.developer.com/open-source/using-graphics-in-javafx/">https://www.developer.com/open-source/using-graphics-in-javafx/</a></dd>
<dt>JavaFX - Main website</dt><dd><a href="https://openjfx.io/">https://openjfx.io/</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-73553046777646278772023-10-19T16:32:00.044+02:002023-10-19T16:32:00.136+02:00Combining two collections using streams<p>So, I have two collections, and I wish to combine both lists somehow.</p>
<p>Requirements are thusly:</p>
<ul><li>I have a collection newPersons</li>
<li>I have a collection oldPersons</li>
<li>I want a collection containing all the oldPersons but replaced (*some of) the oldPersons with the newPersons (based on id).</li>
</ul>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> record <span style="color: #0066BB; font-weight: bold">Person</span><span style="color: #333333">(</span>Long id<span style="color: #333333">,</span> String name<span style="color: #333333">,</span> String surname<span style="color: #333333">)</span> <span style="color: #333333">{</span>
<span style="color: #333333">}</span>
</pre></div>
<p>Using the record class above.</p>
<h2>Solution 1.</h2>
<p>Create a new list based on oldPersons, replace items in this new list with equivalent items in newPersons.</p>
<p>This solution leaves much to be desired. It's confusing and error prone.</p>
<p>I was looking for something better.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #008800; font-weight: bold">public</span> List<span style="color: #333333"><</span>Person<span style="color: #333333">></span> <span style="color: #0066BB; font-weight: bold">mergeMetadata</span><span style="color: #333333">(</span>List<span style="color: #333333"><</span>Person<span style="color: #333333">></span> newPersons<span style="color: #333333">,</span>
List<span style="color: #333333"><</span>Person<span style="color: #333333">></span> oldPersons<span style="color: #333333">)</span> <span style="color: #333333">{</span>
var result <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>(</span>oldPersons<span style="color: #333333">);</span>
newPersons<span style="color: #333333">.</span><span style="color: #0000CC">forEach</span><span style="color: #333333">(</span>newPerson <span style="color: #333333">-></span> <span style="color: #333333">{</span>
result<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>person <span style="color: #333333">-></span> person<span style="color: #333333">.</span><span style="color: #0000CC">id</span><span style="color: #333333">().</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>newPerson<span style="color: #333333">.</span><span style="color: #0000CC">id</span><span style="color: #333333">()))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">ifPresent</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">result:</span><span style="color: #333333">:</span>remove<span style="color: #333333">);</span>
result<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span>newPerson<span style="color: #333333">);</span>
<span style="color: #333333">});</span>
<span style="color: #008800; font-weight: bold">return</span> result<span style="color: #333333">;</span>
<span style="color: #333333">}</span>
</pre></div>
<h2>Solution 2.</h2>
<p>Sometimes getting back to our roots using for-loops can help readability.</p>
<p>We could try it the other way around, see if that helps.</p>
<p>This time we create a new list based on newPersons and add an oldPerson if it's not already in the list.</p>
<p>This seems a little more clear.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #008800; font-weight: bold">public</span> List<span style="color: #333333"><</span>Person<span style="color: #333333">></span> <span style="color: #0066BB; font-weight: bold">mergeMetadata</span><span style="color: #333333">(</span>List<span style="color: #333333"><</span>Person<span style="color: #333333">></span> newPersons<span style="color: #333333">,</span>
List<span style="color: #333333"><</span>Person<span style="color: #333333">></span> oldPersons<span style="color: #333333">)</span> <span style="color: #333333">{</span>
var result <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>(</span>newPersons<span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">for</span> <span style="color: #333333">(</span>Person oldPerson <span style="color: #333333">:</span> oldPersons<span style="color: #333333">)</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>result<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">().</span><span style="color: #0000CC">noneMatch</span><span style="color: #333333">(</span>x <span style="color: #333333">-></span> x<span style="color: #333333">.</span><span style="color: #0000CC">id</span><span style="color: #333333">().</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>oldPerson<span style="color: #333333">.</span><span style="color: #0000CC">id</span><span style="color: #333333">())))</span> <span style="color: #333333">{</span>
result<span style="color: #333333">.</span><span style="color: #0000CC">add</span><span style="color: #333333">(</span>oldPerson<span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">return</span> result<span style="color: #333333">;</span>
<span style="color: #333333">}</span>
</pre></div>
<h2>Solution 3.</h2>
<p>Merge two collections into one list, by using a map.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #008800; font-weight: bold">public</span> List<span style="color: #333333"><</span>Person<span style="color: #333333">></span> <span style="color: #0066BB; font-weight: bold">mergeMetadata</span><span style="color: #333333">(</span>List<span style="color: #333333"><</span>Person<span style="color: #333333">></span> newPersons<span style="color: #333333">,</span>
List<span style="color: #333333"><</span>Person<span style="color: #333333">></span> oldPersons<span style="color: #333333">)</span> <span style="color: #333333">{</span>
Map<span style="color: #333333"><</span>Long<span style="color: #333333">,</span> Person<span style="color: #333333">></span> result <span style="color: #333333">=</span> Stream
<span style="color: #333333">.</span><span style="color: #0000CC">concat</span><span style="color: #333333">(</span>newPersons<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">(),</span> oldPersons<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">())</span>
<span style="color: #333333">.</span><span style="color: #0000CC">collect</span><span style="color: #333333">(</span>Collectors<span style="color: #333333">.</span><span style="color: #0000CC">toMap</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">Person:</span><span style="color: #333333">:</span>id<span style="color: #333333">,</span> Function<span style="color: #333333">.</span><span style="color: #0000CC">identity</span><span style="color: #333333">(),</span> <span style="color: #333333">(</span>l<span style="color: #333333">,</span> r<span style="color: #333333">)</span> <span style="color: #333333">-></span> l<span style="color: #333333">));</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>(</span>result<span style="color: #333333">.</span><span style="color: #0000CC">values</span><span style="color: #333333">());</span>
<span style="color: #333333">}</span>
</pre></div>
<p>Although this solution seems to be the shortest (in code), using a Map function can be a bit daunting (it was for me) because of inherent complexity in the method call for creating it.</p>
<p>Still, perhaps it's just me and my inexperience with combining maps and streams.</p>
<p>I don't know if there's an even better way. Will keep an eye out.</p>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-21877151388309067382023-10-12T10:18:00.008+02:002023-10-12T10:18:00.148+02:00Optional Anti-Pattern<p>It might seem obvious, but recently I saw a colleague use Optional in a weird way.</p>
<p>When I see a piece of code that seems to contain about 3 or more Optional.isPresent() if checks and Optional.get() method calls, I kind of panic.</p>
<p>To be absolutely fair, the code wasn't ready yet, so was going to change anyways.</p>
<p>So, anyways, before we had Optionals, we had to deal with NULL a lot.</p>
<p>The way to do this was as follows:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #008800; font-weight: bold">private</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">documentAccessAllowed</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
Information information <span style="color: #333333">=</span> session<span style="color: #333333">.</span><span style="color: #0000CC">getInformation</span><span style="color: #333333">();</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>information <span style="color: #333333">!=</span> <span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">)</span> <span style="color: #333333">{</span>
Document document <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getDocument</span><span style="color: #333333">(</span>information<span style="color: #333333">.</span><span style="color: #0000CC">getDocumentnumber</span><span style="color: #333333">());</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>document <span style="color: #333333">!=</span> <span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">)</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(!</span>document<span style="color: #333333">.</span><span style="color: #0000CC">getOwner</span><span style="color: #333333">().</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>user<span style="color: #333333">))</span> <span style="color: #333333">{</span>
Administrator administrator <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getAdmininstrator</span><span style="color: #333333">(</span>user<span style="color: #333333">.</span><span style="color: #0000CC">getName</span><span style="color: #333333">());</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>administrator <span style="color: #333333">==</span> <span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">)</span> <span style="color: #333333">{</span>
addErrorMessage<span style="color: #333333">(</span><span style="background-color: #fff0f0">"You are not allowed access to this document."</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">false</span><span style="color: #333333">;</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">true</span><span style="color: #333333">;</span>
<span style="color: #333333">}</span>
</pre></div>
<p>I realize this code could be refactored using "Replace Nested Conditional with Guard Clauses", but some purists frown upon multiple return statements in a method. I don't mind. But let's continue with the example as is.</p>
<p>Then we got Optionals, yay! But, translating the above code verbatim causes my head to explode:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #008800; font-weight: bold">private</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">documentAccessAllowed</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
Optional<span style="color: #333333"><</span>Information<span style="color: #333333">></span> information <span style="color: #333333">=</span> session<span style="color: #333333">.</span><span style="color: #0000CC">getInformation</span><span style="color: #333333">();</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>information<span style="color: #333333">.</span><span style="color: #0000CC">isPresent</span><span style="color: #333333">())</span> <span style="color: #333333">{</span>
Optional<span style="color: #333333"><</span>Document<span style="color: #333333">></span> document <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getDocument</span><span style="color: #333333">(</span>information<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">getDocumentnumber</span><span style="color: #333333">());</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>document<span style="color: #333333">.</span><span style="color: #0000CC">isPresent</span><span style="color: #333333">())</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(!</span>document<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">().</span><span style="color: #0000CC">getOwner</span><span style="color: #333333">().</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>user<span style="color: #333333">))</span> <span style="color: #333333">{</span>
Optional<span style="color: #333333"><</span>Administrator<span style="color: #333333">></span> administrator <span style="color: #333333">=</span> database<span style="color: #333333">.</span><span style="color: #0000CC">getAdmininstrator</span><span style="color: #333333">(</span>user<span style="color: #333333">.</span><span style="color: #0000CC">getName</span><span style="color: #333333">());</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>administrator<span style="color: #333333">.</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">())</span> <span style="color: #333333">{</span>
addErrorMessage<span style="color: #333333">(</span><span style="background-color: #fff0f0">"You are not allowed access to this document."</span><span style="color: #333333">);</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">false</span><span style="color: #333333">;</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">true</span><span style="color: #333333">;</span>
<span style="color: #333333">}</span>
</pre></div>
<p>This code is of course hardly ideal!</p>
<p>A better way is to use the flatMap and map and filter functions of Optional, which seems more concise, but requires a bit of a mental adjustment.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #008800; font-weight: bold">private</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">documentAccessAllowed</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
Boolean allowed <span style="color: #333333">=</span> session<span style="color: #333333">.</span><span style="color: #0000CC">getInformation</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">map</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">Information:</span><span style="color: #333333">:</span>getDocumentnumber<span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">flatMap</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">database:</span><span style="color: #333333">:</span>getDocument<span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>doc <span style="color: #333333">-></span> <span style="color: #333333">!</span>doc<span style="color: #333333">.</span><span style="color: #0000CC">getOwner</span><span style="color: #333333">().</span><span style="color: #0000CC">equals</span><span style="color: #333333">(</span>user<span style="color: #333333">))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>doc <span style="color: #333333">-></span> database<span style="color: #333333">.</span><span style="color: #0000CC">getAdmininstrator</span><span style="color: #333333">(</span>user<span style="color: #333333">.</span><span style="color: #0000CC">getName</span><span style="color: #333333">()).</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">())</span>
<span style="color: #333333">.</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">();</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(!</span>allowed<span style="color: #333333">)</span> <span style="color: #333333">{</span>
addErrorMessage<span style="color: #333333">(</span><span style="background-color: #fff0f0">"You are not allowed access to this document."</span><span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">return</span> allowed<span style="color: #333333">;</span>
<span style="color: #333333">}</span>
</pre></div>
<p>The advice of a colleague of mine is that lambdas, even slightly trivial ones, are a bit hard to read, and making it a method with a good name helps clear things up immensely, like so:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">private</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">documentAccessAllowed</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
<span style="color: #333399; font-weight: bold">boolean</span> allowed <span style="color: #333333">=</span> session<span style="color: #333333">.</span><span style="color: #0000CC">getInformation</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">map</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">Information:</span><span style="color: #333333">:</span>getDocumentnumber<span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">flatMap</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">database:</span><span style="color: #333333">:</span>getDocument<span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>doc <span style="color: #333333">-></span> <span style="color: #333333">!</span>isOwner<span style="color: #333333">(</span>user<span style="color: #333333">,</span> doc<span style="color: #333333">))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>doc <span style="color: #333333">-></span> <span style="color: #333333">!</span>isAdministrator<span style="color: #333333">(</span>database<span style="color: #333333">,</span> user<span style="color: #333333">))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">();</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(!</span>allowed<span style="color: #333333">)</span> <span style="color: #333333">{</span>
addErrorMessage<span style="color: #333333">(</span><span style="background-color: #fff0f0">"You are not allowed access to this document."</span><span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">return</span> allowed<span style="color: #333333">;</span>
<span style="color: #333333">}</span>
</pre></div>
<p>The idea here is not to make the code short (although that most often helps) but make the code very easy to read and follow.</p>
<p>In the example above, there's a lot of use of negation, which I don't like either. (isEmpty(), !isAdmin, !isOwner) Sometimes shoehorning boolean expressions so you can put them in sequential filters is a bad idea. Perhaps the following is more clear:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #008800; font-weight: bold">private</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">documentAccessAllowed</span><span style="color: #333333">(</span>Session session<span style="color: #333333">,</span> Database database<span style="color: #333333">,</span> User user<span style="color: #333333">)</span> <span style="color: #333333">{</span>
<span style="color: #333399; font-weight: bold">boolean</span> allowed <span style="color: #333333">=</span> session<span style="color: #333333">.</span><span style="color: #0000CC">getInformation</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">map</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">Information:</span><span style="color: #333333">:</span>getDocumentnumber<span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">flatMap</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">database:</span><span style="color: #333333">:</span>getDocument<span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>doc <span style="color: #333333">-></span> isOwnerOrAdministrator<span style="color: #333333">(</span>database<span style="color: #333333">,</span> user<span style="color: #333333">,</span> doc<span style="color: #333333">))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">isPresent</span><span style="color: #333333">();</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(!</span>allowed<span style="color: #333333">)</span> <span style="color: #333333">{</span>
addErrorMessage<span style="color: #333333">(</span><span style="background-color: #fff0f0">"You are not allowed access to this document."</span><span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">return</span> allowed<span style="color: #333333">;</span>
<span style="color: #333333">}</span>
<span style="color: #008800; font-weight: bold">private</span> <span style="color: #008800; font-weight: bold">static</span> <span style="color: #333399; font-weight: bold">boolean</span> <span style="color: #0066BB; font-weight: bold">isOwnerOrAdministrator</span><span style="color: #333333">(</span>Database database<span style="color: #333333">,</span> User user<span style="color: #333333">,</span> Document doc<span style="color: #333333">)</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #0066BB; font-weight: bold">isOwner</span><span style="color: #333333">(</span>user<span style="color: #333333">,</span> doc<span style="color: #333333">)</span> <span style="color: #333333">||</span> isAdministrator<span style="color: #333333">(</span>database<span style="color: #333333">,</span> user<span style="color: #333333">);</span>
<span style="color: #333333">}</span>
</pre></div>
<p>Let me know if you have any suggestions, of which there are no doubt several, on how this can be improved in readability.</p>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-13815182425749452412023-10-05T11:52:00.012+02:002023-10-05T11:52:00.139+02:00Creating an @plantuml Javadoc Custom Taglet<p>I love PlantUML, easily create UML diagrams using a description instead of having to draw them myself.</p>
<p>One thing I didn't like was the need to have to install the library GraphViz<sup>1</sup> everywhere, where I wanted to use PlantUML.</p>
<p>But imagine my surprise when I found out, that I don't need to any more.</p>
<p>The java library Smetana<sup>2</sup>, which apparently functions as a drop in replacement for GraphViz should work exactly the same. And it's already integrated in PlantUML!</p>
<p>Can things get any better?</p>
<p>So, once more, let me integrate it into my javadoc build workflow of my sample Java Project using maven.</p>
<p>I had the idea to create a Java Doclet for generating my javadoc, but I quickly realised I should be making a PlantUML Taglet instead. It's already been done, see [3], but I wanted something a little different. But I did get some good ideas from that site.</p>
<p>I wanted to inline the imagedata in the src attribute of the image tag, that seems nicer than separate png files.</p>
<p>I also wanted to use the Smetana by default.</p>
<p>I managed it and uploaded it on the github<sup>4</sup>.</p>
<h2>Maven integration</h2>
<p>Adding the custom taglet to your pom.xml in the javadoc plugin should be enough. You do need to have my custom Taglet installed in your maven .m2/repository directory though.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007700"><plugin></span>
<span style="color: #007700"><groupId></span>org.apache.maven.plugins<span style="color: #007700"></groupId></span>
<span style="color: #007700"><artifactId></span>maven-javadoc-plugin<span style="color: #007700"></artifactId></span>
<span style="color: #007700"><version></span>3.6.0<span style="color: #007700"></version></span>
<span style="color: #007700"><configuration></span>
<span style="color: #007700"><taglet></span>org.taglet.plantuml.PlantumlTaglet<span style="color: #007700"></taglet></span>
<span style="color: #888888"><!-- <tagletpath>/path/to/taglet.jar</tagletpath> --></span>
<span style="color: #007700"><tagletArtifact></span>
<span style="color: #007700"><groupId></span>org.taglet.plantuml<span style="color: #007700"></groupId></span>
<span style="color: #007700"><artifactId></span>plantumltaglet<span style="color: #007700"></artifactId></span>
<span style="color: #007700"><version></span>1.0<span style="color: #007700"></version></span>
<span style="color: #007700"></tagletArtifact></span>
<span style="color: #007700"></configuration></span>
<span style="color: #007700"></plugin></span>
</pre></div>
<p>The following is sufficient to run javadoc and generate the diagrams:</p>
<div class="code">mvn javadoc:javadoc</div>
<h2>Eating your own dogfood</h2>
<p>It also serves as a good example of eating your own dog food<sup>5</sup>.</p>
<p>That's right!</p>
<p>I added PlantUML diagrams to the javadocs of my new PlantUML Taglet, and generated the javadoc+diagrams using my PlantUML Taglet!</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">/**</span>
<span style="color: #888888"> * Created PlantUML Diagrams based on a plantuml description.</span>
<span style="color: #888888"> * @plantuml</span>
<span style="color: #888888"> * PlantumlImageDataFactory : +getImageData(plantuml: String): String</span>
<span style="color: #888888"> */</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">class</span> <span style="color: #BB0066; font-weight: bold">PlantumlImageDataFactory</span> <span style="color: #333333">{</span>
</pre></div>
<p>Worked like a charm!</p>
<p>It will look like this:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7JMkM5dYXzE70azDOl-ErHfhotaLgXoi4UenldFzFGUP4faYgtqWuObCaB_Z9_9EbpDEk44mOXDRDeaInjFLzVE0VnCVzeX88HVUuULAN7CXsjrSjhF2qKV67lAqNwuqn_HQsR2HzoOUuipyO9FVAgUK6g7Q0XrBZ9DBbRhuo5OztodFmMkNwJvItaaGd/s880/Screenshot%202023-10-03%20at%2009.08.33.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="601" data-original-width="880" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7JMkM5dYXzE70azDOl-ErHfhotaLgXoi4UenldFzFGUP4faYgtqWuObCaB_Z9_9EbpDEk44mOXDRDeaInjFLzVE0VnCVzeX88HVUuULAN7CXsjrSjhF2qKV67lAqNwuqn_HQsR2HzoOUuipyO9FVAgUK6g7Q0XrBZ9DBbRhuo5OztodFmMkNwJvItaaGd/s320/Screenshot%202023-10-03%20at%2009.08.33.png"/></a></div>
<p>The image will be as raw data in the html source code, like so:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007700"><section</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"class-description"</span> <span style="color: #0000CC">id=</span><span style="background-color: #fff0f0">"class-description"</span><span style="color: #007700">></span>
<span style="color: #007700"><dl</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"notes"</span><span style="color: #007700">></span>
<span style="color: #007700"><dt></span>All Implemented Interfaces:<span style="color: #007700"></dt></span>
<span style="color: #007700"><dd><code><a</span> <span style="color: #0000CC">href=</span><span style="background-color: #fff0f0">"https://docs.oracle.com/en/java/javase/17/docs/api/jdk.javadoc/jdk/javadoc/doclet/Taglet.html"</span> <span style="color: #0000CC">title=</span><span style="background-color: #fff0f0">"class or interface in jdk.javadoc.doclet"</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"external-link"</span><span style="color: #007700">></span>Taglet<span style="color: #007700"></a></code></dd></span>
<span style="color: #007700"></dl></span>
<span style="color: #007700"><hr></span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"type-signature"</span><span style="color: #007700">><span</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"modifiers"</span><span style="color: #007700">></span>public class <span style="color: #007700"></span><span</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"element-name type-name-label"</span><span style="color: #007700">></span>PlantumlTaglet<span style="color: #007700"></span></span>
<span style="color: #007700"><span</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"extends-implements"</span><span style="color: #007700">></span>extends <span style="color: #007700"><a</span> <span style="color: #0000CC">href=</span><span style="background-color: #fff0f0">"https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html"</span> <span style="color: #0000CC">title=</span><span style="background-color: #fff0f0">"class or interface in java.lang"</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"external-link"</span><span style="color: #007700">></span>Object<span style="color: #007700"></a></span>
implements <span style="color: #007700"><a</span> <span style="color: #0000CC">href=</span><span style="background-color: #fff0f0">"https://docs.oracle.com/en/java/javase/17/docs/api/jdk.javadoc/jdk/javadoc/doclet/Taglet.html"</span> <span style="color: #0000CC">title=</span><span style="background-color: #fff0f0">"class or interface in jdk.javadoc.doclet"</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"external-link"</span><span style="color: #007700">></span>Taglet<span style="color: #007700"></a></span></div></span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"block"</span><span style="color: #007700">></span>A Taglet made by me to convert appropriate Plantuml codes into generated diagrams. Uses layout smetana instead
of GraphViz.<span style="color: #007700"></div></span>
<span style="color: #007700"><dl</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"notes"</span><span style="color: #007700">></span>
<span style="color: #007700"><dt></span>See Also:<span style="color: #007700"></dt></span>
<span style="color: #007700"><dd></span>
<span style="color: #007700"><ul</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"tag-list"</span><span style="color: #007700">></span>
<span style="color: #007700"><li><a</span> <span style="color: #0000CC">href=</span><span style="background-color: #fff0f0">"https://mnlipp.github.io/jdrupes-taglets/plantuml-taglet/javadoc/index.html"</span><span style="color: #007700">></span>PlantUML Taglet<span style="color: #007700"></a></li></span>
<span style="color: #007700"></ul></span>
<span style="color: #007700"></dd></span>
<span style="color: #007700"><p><img</span> <span style="color: #0000CC">alt=</span><span style="background-color: #fff0f0">"umldiagram"</span> <span style="color: #0000CC">src=</span><span style="background-color: #fff0f0">"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAhMAAAC2CAIAAADsj5gHAAAAKnRFWHRjb3B5bGVmdABHZW5lcmF0ZWQgYnkgaHR0cHM6Ly9wbGFudHVtbC5jb212z..."</span> <span style="color: #007700">/></p></dl></span>
<span style="color: #007700"></section></span>
</pre></div>
<h1>References</h1>
<dl>
<dt>[1] PlantUML - GraphViz-Dot</dt><dd><a href="https://plantuml.com/graphviz-dot">https://plantuml.com/graphviz-dot</a></dd>
<dt>[2] PlantUML - Porting GraphViz to Java</dt><dd><a href="https://plantuml.com/smetana02">https://plantuml.com/smetana02</a></dd>
<dt>[3] PlantUML Taglet</dt><dd><a href="https://mnlipp.github.io/jdrupes-taglets/plantuml-taglet/javadoc/index.html">https://mnlipp.github.io/jdrupes-taglets/plantuml-taglet/javadoc/index.html</a></dd>
<dt>[4] Github.com - PlantUML Taglet</dt><dd><a href="https://github.com/maartenl/plantumltaglet">https://github.com/maartenl/plantumltaglet</a></dd>
<dt>[5] Wikipedia - Eating your own dog food</dt><dd><a href="https://en.wikipedia.org/wiki/Eating_your_own_dog_food">https://en.wikipedia.org/wiki/Eating_your_own_dog_food</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-41045226362631561522023-09-28T14:10:00.000+02:002023-09-28T14:10:00.153+02:00Dependency Injection<p>Found a good explanation of Dependency Injection, one of the pillars of CDI.</p>
<p>Of course, the original text by Martin Fowler<sup>2</sup> is also well worth the read, but if you want to get into details of JEE, [1] is very good.</p>
<p>It works great, of course sometimes I screw it up, and then I get errors that need to be resolved, for instance:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">org.jboss.weld.exceptions.DeploymentException: Exception List with 8 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001443: Pseudo scoped bean has circular dependencies. Dependency path:
- Managed Bean [class com.mrbear.OrderService] with qualifiers [@Any @Default],
- [BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject public com.mrbear.OrderService(AddressService, x, y, z),
- Managed Bean [class com.mrbear.AddressService] with qualifiers [@Any @Default],
- [BackedAnnotatedParameter] Parameter 11 of [BackedAnnotatedConstructor] @Inject public com.mrbear.AddressService(a, b, c, d, e, f, g, h, I, j, OrderSupplier),
- Managed Bean [class com.mrbear.OrderSupplier with qualifiers [@Any @Default],
- [BackedAnnotatedParameter] Parameter 7 of [BackedAnnotatedConstructor] @Inject public com.mrbear.OrderFactory(a, b, c, d, e, f, CityTownVillageSearchService),
- Managed Bean [class com.mrbear.CityTownVillageSearchService] with qualifiers [@Any @Default],
- [BackedAnnotatedField] @Inject private com.mrbear.CityTownVillageSearchService.OrderSupplier,
- Managed Bean [class com.mrbear.OrderFactory] with qualifiers [@Any @Default]
at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:924)
at org.jboss.weld.bootstrap.Validator.validatePseudoScopedInjectionPoint(Validator.java:971)
at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:933)
at org.jboss.weld.bootstrap.Validator.validatePseudoScopedInjectionPoint(Validator.java:971)
at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:933)
at org.jboss.weld.bootstrap.Va
</pre></div>
<p>Funnily enough, circular dependencies seemed to work fine when using Enterprise Beans or some such. I guess it depends a little on the implementation.</p>
<h1>References</h1>
<dl>
<dt>[1] JBoss Weld Reference - Chapter 4. Dependency injection and programmatic lookup</dt>
<dd><a href="https://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/injection.html">https://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/injection.html</a></dd>
<dt>[2] MartinFowler.com - Inversion of Control Containers and the Dependency Injection pattern</dt>
<dd><a href="https://martinfowler.com/articles/injection.html">https://martinfowler.com/articles/injection.html</a></dd>
</dl>Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-35852515825164893612023-09-21T09:38:00.001+02:002023-09-21T09:38:00.139+02:00How to get started with Java as quickly as possible<p>Apparently, Java 21 has some new things<sup>1</sup> to make it easier to get started with Java<sup>2</sup> right away.</p>
<p>So this is the ultimate blogpost of mine to get started quickly and easily.</p>
<p><strong>Fair warning</strong>: I'm using the macos version of Java, so the directory structure might be a bit different compared to other Operating Systems.</p>
<h2>Step 1. Download java</h2>
<p>Go to <a href="https://jdk.java.net/21">https://jdk.java.net/21</a> and download the build you need.</p>
<h2>Step 2. Unpack</h2>
<p>Unpack the archive somewhere.</p>
<div class="code">% tar zxvf Downloads/openjdk-21_macos-x64_bin.tar.gz</div>
<p>It will unpack in directory <tt>jdk-21.jdk</tt>.</p>
<h2>Step 3. Write a small Java program</h2>
<p>In this instance, we'll assume the file is called <tt>HelloWorld.java</tt>.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">main</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
System<span style="color: #333333">.</span><span style="color: #0000CC">out</span><span style="color: #333333">.</span><span style="color: #0000CC">println</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"Hello, world."</span><span style="color: #333333">);</span>
<span style="color: #333333">}</span>
</pre></div>
<h2>Step 4. Run the small Java program</h2>
<div class="code">% ~/jdk-21.jdk/Contents/Home/bin/java --enable-preview --source 21 ./HelloWorld.java<br/>
Note: ./HelloWorld.java uses preview features of Java SE 21.<br/>
Note: Recompile with -Xlint:preview for details.<br/>
Hello, world.</div>
<p>Congratulations, you've run your first Java Program!</p>
<p>The other way to do it, which admittedly is even quicker, is using the Java Playground<sup>3</sup>.</p>
<h1>References</h1>
<dl>
<dt>[1] JEP 445: Unnamed Classes and Instance Main Methods (Preview)</dt><dd><a href="https://openjdk.org/jeps/445">https://openjdk.org/jeps/445</a></dd>
<dt>[2] Paving the on-ramp</dt><dd><a href="https://randomthoughtsonjavaprogramming.blogspot.com/2022/10/paving-on-ramp.html">https://randomthoughtsonjavaprogramming.blogspot.com/2022/10/paving-on-ramp.html</a></dd>
<dt>[3] dev.java - Java Playground</dt><dd><a href="https://dev.java/playground/">https://dev.java/playground/</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-81425160379023816872023-09-19T09:16:00.000+02:002023-09-19T09:16:02.154+02:00Java 21 Release - Launch Event<p>All right! Java 21 is scheduled for General Availability<sup>1</sup> on 2023/09/19! That's today!</p>
<p>Apparently there's an appropriate launch event<sup>2 3</sup> as well!</p>
<p>And it's a Long Term Supported release (LTS), so that's good.</p>
<p>Hoping to see support for it everywhere.</p>
<h1>References</h1>
<dl>
<dt>[1] OpenJDK Java 21</dt><dd><a href="https://openjdk.org/projects/jdk/21/">https://openjdk.org/projects/jdk/21/</a></dd>
<dt>[2] Java 21 Launch Event</dt><dd><a href="https://dev.java/community/java-21-launch/">https://dev.java/community/java-21-launch/</a></dd>
<dt>[3] YouTube.com - Java 21 Launch Event
</dt><dd><a href="https://www.youtube.com/watch?v=E8NV68ihJyY">https://www.youtube.com/watch?v=E8NV68ihJyY</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-5595834292986222862023-09-07T13:20:00.002+02:002023-09-07T13:20:00.145+02:0010 Common Mistakes Java Developers Make when Writing SQL<p>Just some references to very important articles about common mistakes Java Developers make when trying to write SQL statements.</p>
<p>Just putting it here, in case I forget.</p>
<p>Because let's be honest here, I've committed quite a few in my time.</p>
<h1>References</h1>
<dl>
<dt>JAVA, SQL AND JOOQ. - 10 Common Mistakes Java Developers Make when Writing SQL</dt>
<dd><a href="https://blog.jooq.org/10-common-mistakes-java-developers-make-when-writing-sql/">https://blog.jooq.org/10-common-mistakes-java-developers-make-when-writing-sql/</a></dd>
<dt>JAVA, SQL AND JOOQ. - 10 More Common Mistakes Java Developers Make when Writing SQL</dt>
<dd><a href="https://blog.jooq.org/10-more-common-mistakes-java-developers-make-when-writing-sql/">https://blog.jooq.org/10-more-common-mistakes-java-developers-make-when-writing-sql/</a></dd>
<dt>JAVA, SQL AND JOOQ. - Yet Another 10 Common Mistakes Java Developers Make When Writing SQL (You Won’t BELIEVE the Last One)</dt>
<dd><a href="https://blog.jooq.org/yet-another-10-common-mistakes-java-developer-make-when-writing-sql-you-wont-believe-the-last-one/">https://blog.jooq.org/yet-another-10-common-mistakes-java-developer-make-when-writing-sql-you-wont-believe-the-last-one/</a></dd></dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-80891751180159658662023-07-13T16:48:00.001+02:002023-07-13T16:48:00.147+02:00Using FindFirst in an Odd Way?<p>So I have a list, and I'm pretty sure it's either empty or contains one element.</p>
<p>So I was thinking too hard, and fabricated something like this:<?p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> Optional<span style="color: #333333"><</span>Item<span style="color: #333333">></span> <span style="color: #0066BB; font-weight: bold">getItem</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">return</span> items<span style="color: #333333">.</span><span style="color: #0000CC">isEmpty</span><span style="color: #333333">()</span> <span style="color: #333333">?</span> Optional<span style="color: #333333">.</span><span style="color: #0000CC">empty</span><span style="color: #333333">()</span> <span style="color: #333333">:</span> Optional<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span>items<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">0</span><span style="color: #333333">)));</span>
<span style="color: #333333">}</span>
</pre></div>
<p>And then I thought: "What am I thinking!?" and used the stream API instead:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> Optional<span style="color: #333333"><</span>Item<span style="color: #333333">></span> <span style="color: #0066BB; font-weight: bold">getItem</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">return</span> items<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">().</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">();</span>
<span style="color: #333333">}</span>
</pre></div>
<p>There.</p><p>Seems easy enough.</p>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-12778449466725703162023-07-06T08:22:00.001+02:002023-07-06T08:22:00.155+02:00Turning off Hazelcast in Payara Micro<p>Just wanted to turn off hazelcast in my Payara Micro instance.</p>
<p>I've tried putting the following in my postboot file, but that doesn't work:</p><div class="code">set-hazelcast-configuration --enabled=false</div>
<p>A quick google search found reference [1].</p>
<p>Just adding <tt>--nocluster</tt> as a commandline parameter when running Payara Micro does the trick.</p>
<h1>References</h1>
<dl><dt>[1] Payara Forums - Can’t disable Hazelcast with payara-micro-maven-plugin prebootcommandfile</dt><dd><a href="https://forum.payara.fish/t/cant-disable-hazelcast-with-payara-micro-maven-plugin-prebootcommandfile/321/2">https://forum.payara.fish/t/cant-disable-hazelcast-with-payara-micro-maven-plugin-prebootcommandfile/321/2</a></dd></dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-56123449861835986602023-06-29T08:31:00.000+02:002023-06-29T08:31:06.041+02:00How to install Javascript Engine in GraalVM<p>I've already mentioned it in the reference below, but just for easy reference for me.</p>
<p>The JavaScript engine no longer comes installed by default in the GraalVM. You have to install it as follows:</p>
<div class="code">
% ./gu install js<br>
Downloading: Artifacts catalog from gds.oracle.com<br>
Skipping ULN EE channels, no username provided.<br>
Downloading: Component catalog from www.graalvm.org<br>
Processing Component: Graal.js<br>
Processing Component: ICU4J<br>
Processing Component: TRegex<br>
Additional Components are required:<br>
ICU4J (org.graalvm.icu4j, version 23.0.0), required by: Graal.js (org.graalvm.js)<br>
TRegex (org.graalvm.regex, version 23.0.0), required by: Graal.js (org.graalvm.js)<br>
Downloading: Component js: Graal.js from gds.oracle.com<br>
Downloading: Component org.graalvm.icu4j: ICU4J from gds.oracle.com<br>
Downloading: Component org.graalvm.regex: TRegex from gds.oracle.com<br>
Installing new component: TRegex (org.graalvm.regex, version 23.0.0)<br>
Installing new component: ICU4J (org.graalvm.icu4j, version 23.0.0)<br>
Installing new component: Graal.js (org.graalvm.js, version 23.0.0)
</div>
<h1>References</h1>
<dl>
<dt>Upgrading to Jakarta 10
</dt><dd><a href="https://randomthoughtsonjavaprogramming.blogspot.com/2022/12/upgrading-to-jakarta-10.html">https://randomthoughtsonjavaprogramming.blogspot.com/2022/12/upgrading-to-jakarta-10.html</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-53920216845358480922023-06-15T10:23:00.001+02:002023-06-15T10:23:00.146+02:00NullPointerException in Stream<p>Just a small blurb. I recently helped a colleague who got a NullPointerException whilst dealing with streams.</p>
<p>It looked very innocuous at first.</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #555555; font-weight: bold">@Test</span><span style="color: #333333">(</span>expectedExceptions <span style="color: #333333">=</span> NullPointerException<span style="color: #333333">.</span><span style="color: #0000CC">class</span><span style="color: #333333">)</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">testStream</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
Optional<span style="color: #333333"><</span>String<span style="color: #333333">></span> first <span style="color: #333333">=</span> Stream<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="color: #008800; font-weight: bold">null</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"mrBear"</span><span style="color: #333333">),</span> <span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="background-color: #fff0f0">"George"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Boole"</span><span style="color: #333333">),</span>
<span style="color: #008800; font-weight: bold">new</span> <span style="color: #0066BB; font-weight: bold">Person</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"Ada"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Lovelace"</span><span style="color: #333333">),</span>
<span style="color: #008800; font-weight: bold">new</span> <span style="color: #0066BB; font-weight: bold">Person</span><span style="color: #333333">(</span><span style="background-color: #fff0f0">"Tim"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Berners-Lee"</span><span style="color: #333333">),</span> <span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="background-color: #fff0f0">"James"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Gosling"</span><span style="color: #333333">),</span> <span style="color: #008800; font-weight: bold">new</span> Person<span style="color: #333333">(</span><span style="background-color: #fff0f0">"Linus"</span><span style="color: #333333">,</span> <span style="background-color: #fff0f0">"Torvalds"</span><span style="color: #333333">))</span>
<span style="color: #333333">.</span><span style="color: #0000CC">map</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">Person:</span><span style="color: #333333">:</span>firstName<span style="color: #333333">).</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">();</span>
<span style="color: #333333">}</span>
</pre></div>
<p>Well, it turns out that, if you have a list with null-values, and you try a findFirst() on the stream, and the first value is null, Java will attempt to wrap the null-value into an Optional, which is not allowed.</p>
<p>You get a fancy stacktrace, that shows just this:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">java<span style="color: #333333">.</span><span style="color: #0000CC">lang</span><span style="color: #333333">.</span><span style="color: #0000CC">NullPointerException</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>java<span style="color: #333333">.</span><span style="color: #0000CC">util</span><span style="color: #333333">.</span><span style="color: #0000CC">Objects</span><span style="color: #333333">.</span><span style="color: #0000CC">requireNonNull</span><span style="color: #333333">(</span>Objects<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">208</span><span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>java<span style="color: #333333">.</span><span style="color: #0000CC">util</span><span style="color: #333333">.</span><span style="color: #0000CC">Optional</span><span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span>Optional<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">113</span><span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>java<span style="color: #333333">.</span><span style="color: #0000CC">util</span><span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">.</span><span style="color: #0000CC">FindOps</span>$FindSink$OfRef<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">(</span>FindOps<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">194</span><span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>java<span style="color: #333333">.</span><span style="color: #0000CC">util</span><span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">.</span><span style="color: #0000CC">FindOps</span>$FindSink$OfRef<span style="color: #333333">.</span><span style="color: #0000CC">get</span><span style="color: #333333">(</span>FindOps<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">191</span><span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>java<span style="color: #333333">.</span><span style="color: #0000CC">util</span><span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">.</span><span style="color: #0000CC">FindOps</span>$FindOp<span style="color: #333333">.</span><span style="color: #0000CC">evaluateSequential</span><span style="color: #333333">(</span>FindOps<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">150</span><span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>java<span style="color: #333333">.</span><span style="color: #0000CC">util</span><span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">.</span><span style="color: #0000CC">AbstractPipeline</span><span style="color: #333333">.</span><span style="color: #0000CC">evaluate</span><span style="color: #333333">(</span>AbstractPipeline<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">234</span><span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>java<span style="color: #333333">.</span><span style="color: #0000CC">util</span><span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">.</span><span style="color: #0000CC">ReferencePipeline</span><span style="color: #333333">.</span><span style="color: #0000CC">findFirst</span><span style="color: #333333">(</span>ReferencePipeline<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">647</span><span style="color: #333333">)</span>
at com<span style="color: #333333">.</span><span style="color: #0000CC">mrbear</span><span style="color: #333333">.</span><span style="color: #0000CC">streams</span><span style="color: #333333">.</span><span style="color: #0000CC">NullPointerExceptionTest</span><span style="color: #333333">.</span><span style="color: #0000CC">testStream</span><span style="color: #333333">(</span>NullPointerExceptionTest<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">18</span><span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>jdk<span style="color: #333333">.</span><span style="color: #0000CC">internal</span><span style="color: #333333">.</span><span style="color: #0000CC">reflect</span><span style="color: #333333">.</span><span style="color: #0000CC">NativeMethodAccessorImpl</span><span style="color: #333333">.</span><span style="color: #0000CC">invoke0</span><span style="color: #333333">(</span>Native Method<span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>jdk<span style="color: #333333">.</span><span style="color: #0000CC">internal</span><span style="color: #333333">.</span><span style="color: #0000CC">reflect</span><span style="color: #333333">.</span><span style="color: #0000CC">NativeMethodAccessorImpl</span><span style="color: #333333">.</span><span style="color: #0000CC">invoke</span><span style="color: #333333">(</span>NativeMethodAccessorImpl<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">77</span><span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>jdk<span style="color: #333333">.</span><span style="color: #0000CC">internal</span><span style="color: #333333">.</span><span style="color: #0000CC">reflect</span><span style="color: #333333">.</span><span style="color: #0000CC">DelegatingMethodAccessorImpl</span><span style="color: #333333">.</span><span style="color: #0000CC">invoke</span><span style="color: #333333">(</span>DelegatingMethodAccessorImpl<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">43</span><span style="color: #333333">)</span>
at java<span style="color: #333333">.</span><span style="color: #0000CC">base</span><span style="color: #333333">/</span>java<span style="color: #333333">.</span><span style="color: #0000CC">lang</span><span style="color: #333333">.</span><span style="color: #0000CC">reflect</span><span style="color: #333333">.</span><span style="color: #0000CC">Method</span><span style="color: #333333">.</span><span style="color: #0000CC">invoke</span><span style="color: #333333">(</span>Method<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">568</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">internal</span><span style="color: #333333">.</span><span style="color: #0000CC">MethodInvocationHelper</span><span style="color: #333333">.</span><span style="color: #0000CC">invokeMethod</span><span style="color: #333333">(</span>MethodInvocationHelper<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">124</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">internal</span><span style="color: #333333">.</span><span style="color: #0000CC">Invoker</span><span style="color: #333333">.</span><span style="color: #0000CC">invokeMethod</span><span style="color: #333333">(</span>Invoker<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">571</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">internal</span><span style="color: #333333">.</span><span style="color: #0000CC">Invoker</span><span style="color: #333333">.</span><span style="color: #0000CC">invokeTestMethod</span><span style="color: #333333">(</span>Invoker<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">707</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">internal</span><span style="color: #333333">.</span><span style="color: #0000CC">Invoker</span><span style="color: #333333">.</span><span style="color: #0000CC">invokeTestMethods</span><span style="color: #333333">(</span>Invoker<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">979</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">internal</span><span style="color: #333333">.</span><span style="color: #0000CC">TestMethodWorker</span><span style="color: #333333">.</span><span style="color: #0000CC">invokeTestMethods</span><span style="color: #333333">(</span>TestMethodWorker<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">125</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">internal</span><span style="color: #333333">.</span><span style="color: #0000CC">TestMethodWorker</span><span style="color: #333333">.</span><span style="color: #0000CC">run</span><span style="color: #333333">(</span>TestMethodWorker<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">109</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">TestRunner</span><span style="color: #333333">.</span><span style="color: #0000CC">privateRun</span><span style="color: #333333">(</span>TestRunner<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">648</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">TestRunner</span><span style="color: #333333">.</span><span style="color: #0000CC">run</span><span style="color: #333333">(</span>TestRunner<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">505</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">SuiteRunner</span><span style="color: #333333">.</span><span style="color: #0000CC">runTest</span><span style="color: #333333">(</span>SuiteRunner<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">455</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">SuiteRunner</span><span style="color: #333333">.</span><span style="color: #0000CC">runSequentially</span><span style="color: #333333">(</span>SuiteRunner<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">450</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">SuiteRunner</span><span style="color: #333333">.</span><span style="color: #0000CC">privateRun</span><span style="color: #333333">(</span>SuiteRunner<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">415</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">SuiteRunner</span><span style="color: #333333">.</span><span style="color: #0000CC">run</span><span style="color: #333333">(</span>SuiteRunner<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">364</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">SuiteRunnerWorker</span><span style="color: #333333">.</span><span style="color: #0000CC">runSuite</span><span style="color: #333333">(</span>SuiteRunnerWorker<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">52</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">SuiteRunnerWorker</span><span style="color: #333333">.</span><span style="color: #0000CC">run</span><span style="color: #333333">(</span>SuiteRunnerWorker<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">84</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">TestNG</span><span style="color: #333333">.</span><span style="color: #0000CC">runSuitesSequentially</span><span style="color: #333333">(</span>TestNG<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">1187</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">TestNG</span><span style="color: #333333">.</span><span style="color: #0000CC">runSuitesLocally</span><span style="color: #333333">(</span>TestNG<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">1116</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">TestNG</span><span style="color: #333333">.</span><span style="color: #0000CC">runSuites</span><span style="color: #333333">(</span>TestNG<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">1028</span><span style="color: #333333">)</span>
at org<span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">TestNG</span><span style="color: #333333">.</span><span style="color: #0000CC">run</span><span style="color: #333333">(</span>TestNG<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">996</span><span style="color: #333333">)</span>
at com<span style="color: #333333">.</span><span style="color: #0000CC">intellij</span><span style="color: #333333">.</span><span style="color: #0000CC">rt</span><span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">IDEARemoteTestNG</span><span style="color: #333333">.</span><span style="color: #0000CC">run</span><span style="color: #333333">(</span>IDEARemoteTestNG<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">66</span><span style="color: #333333">)</span>
at com<span style="color: #333333">.</span><span style="color: #0000CC">intellij</span><span style="color: #333333">.</span><span style="color: #0000CC">rt</span><span style="color: #333333">.</span><span style="color: #0000CC">testng</span><span style="color: #333333">.</span><span style="color: #0000CC">RemoteTestNGStarter</span><span style="color: #333333">.</span><span style="color: #0000CC">main</span><span style="color: #333333">(</span>RemoteTestNGStarter<span style="color: #333333">.</span><span style="color: #0000CC">java</span><span style="color: #333333">:</span><span style="color: #0000DD; font-weight: bold">105</span><span style="color: #333333">)</span>
</pre></div>
<p>Just something to keep in mind.</p>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-2778983530855778562023-06-09T08:48:00.004+02:002024-02-21T08:31:45.815+01:00Podman<p>Podman is a drop-in replacement for Docker, at least that's what I hear.</p>
<p>From the little experience I currently have, the commands on the command line seem to be almost equivalent if not in syntax at least in intention to Docker.</p>
<h2>Installing Podman</h2>
<div class="code">mrbear % brew install podman</div>
<h2>Running Podman</h2>
<div class="code">
podman machine init<br/>
Downloading VM image: fedora-coreos-38.20230514.2.0-qemu.aarch64.qcow2.xz: done<br/>
Extracting compressed file<br/>
Image resized.<br/>
Machine init complete<br/>
To start your machine run:<br/>
<br/>
podman machine start</div><div class="code">
podman machine start<br/>
Starting machine "podman-machine-default"<br/>
Waiting for VM ...<br/>
Mounting volume... /Users:/Users<br/>
Mounting volume... /private:/private<br/>
Mounting volume... /var/folders:/var/folders<br/>
<br/>
This machine is currently configured in rootless mode. If your containers<br/>
require root permissions (e.g. ports < 1024), or if you run into compatibility<br/>
issues with non-podman clients, you can switch using the following command:<br/>
<br/>
podman machine set --rootful<br/>
<br/>
API forwarding listening on: /Users/mrbear/.local/share/containers/podman/machine/qemu/podman.sock<br/>
<br/>
The system helper service is not installed; the default Docker API socket<br/>
address can't be used by podman. If you would like to install it run the<br/>
following commands:<br/>
<br/>
sudo /opt/homebrew/Cellar/podman/4.5.0/bin/podman-mac-helper install<br/>
podman machine stop; podman machine start<br/>
<br/>
You can still connect Docker API clients by setting DOCKER_HOST using the<br/>
following command in your terminal session:<br/>
<br/>
export DOCKER_HOST='unix:///Users/mrbear/.local/share/containers/podman/machine/qemu/podman.sock'<br/>
<br/>
Machine "podman-machine-default" started successfully</div>
<h2>Verify Podman</h2>
<div class="code">podman info</div>
<h2>A GUI</h2>
<p>I will be trying out Podman Desktop. Under Docker I was very used to Portainer.</p>
<h2>Networking</h2>
<p>Non-root containers use <i>slirp4netns</i> and have no routable IP address. Root containers use <i>netavark</i>.</p>
<h2>Glossary of commands</h2>
<dl>
<dt>podman machine init</dt><dd> initializes the machine</dd>
<dt>podman machine start</dt><dd>starts the machine</dd>
<dt>podman info</dt><dd>verify installation</dd>
<dt>podman ps [-a]</dt><dd>list creating and running containers</dd>
<dt>podman pull <container url></dt><dd>pull an image, for example "podman pull docker.io/library/postgres:14" or simply "podman pull mariadb"</dd>
<dt>podman images</dt><dd>show all images</dd>
<dt>podman rmi <image></dt><dd>remove an image, for example "podman rmi 0c1418f4071b", where the id can be ascertained using "podman images"</dd>
<dt>podman run ...</dt><dd>run a container, for example:
<ul>
<li>podman run --detach --tty --name webserver --publish 8080:80 quay.io/libpod/banner</li>
<li>podman run --name postgres --detach --publish 5432:5432 --env POSTGRES_USER=admin --env POSTGRES_PASSWORD=Passw0rd postgis/postgis</li>
<li>podman run --name postgres --detach --publish 5432:5432 --env POSTGRES_USER=admin --env POSTGRES_PASSWORD=Passw0rd docker.io/library/postgres:latest</li>
<li>podman run --detach --name mariadb --publish 3306:3306 --env MARIADB_USER=root --env MARIADB_PASSWORD=Passw0rd --env MARIADB_ROOT_PASSWORD=Passw0rd docker.io/library/mariadb</li>
</ul>
<dl>
<dt>--detach/-d</dt><dd>run the container in the background and print the new container ID. The default is false.</dd>
<dt>--tty/-t</dt><dd>Allocate a pseudo-TTY. The default is false.</dd>
<dt>--publish/-p [[ip:][hostPort]:]containerPort[/protocol]¶</dt><dd>Publish a container’s port, or range of ports, to the host.</dd>
<dt>--env/-e</dt><dd>Set environment variables.</dd>
<dt>--name</dt><dd>Assign a name to the container.</dd>
</dl>
</dd>
<dt>podman ps</dt><dd>lists the running containers on the system. Use the --all flag to view all the containers information. </dd>
<dt>podman attach <container_id></dt><dd>sttached tty to a running container</dd>
<dt>podman inspect -l</dt><dd>metadata and details about the running containers</dd>
<dt>podman logs <container_id></dt><dd>log container logs</dd>
<dt>podman top <container_id></dt><dd>show processes running in the container</dd>
<dt>podman start <container_id></dt><dd>start a container</dd>
<dt>podman stop <container_id></dt><dd>stop a container</dd>
<dt>podman rm <container_id></dt><dd>remove a container</dd>
</dl>
<p>I'll add to this as I get more information.</p>
<h1>References</h1>
<dl>
<dt>Podman</dt><dd><a href="https://podman.io/">https://podman.io/</a></dd>
<dt>Podman - Installation</dt><dd><a href="https://podman.io/docs/installation">https://podman.io/docs/installation</a></dd>
<dt>TechViewLeo - How To Run PostgreSQL 14|13 in Podman Container</dt><dd><a href="https://techviewleo.com/how-to-run-postgresql-in-podman-container/?utm_content=cmp-true">https://techviewleo.com/how-to-run-postgresql-in-podman-container/?utm_content=cmp-true</a></dd>
<dt>podman desktop</dt><dd><a href="https://podman-desktop.io/">https://podman-desktop.io/</a></dd>
<dt>ImaginaryCloud - Podman vs Docker: What are the differences?</dt><dd><a href="https://www.imaginarycloud.com/blog/podman-vs-docker/">https://www.imaginarycloud.com/blog/podman-vs-docker/</a></dd>
<dt>Portainer</dt><dd><a href="https://www.portainer.io/">https://www.portainer.io/</a></dd>
</dl>
Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0tag:blogger.com,1999:blog-7409597408023081712.post-50286903357641632642023-05-24T10:22:00.002+02:002023-05-24T10:22:50.373+02:00ConcurrentModificationException and Streams - what not to do<p>I was wondering what shenanigans I can get up to with streams and mutating the underlying collection, and what a terrible idea this is.</p>
<p>As we all know, it's a really bad idea to mutate a list on which you are iterating, and Java makes certain this fails with a ConcurrentModificationException.</p>
<p>It all starts with the original problem, a for-loop that also mutates the list on which is iterates:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #555555; font-weight: bold">@Test</span><span style="color: #333333">(</span>expectedExceptions <span style="color: #333333">=</span> ConcurrentModificationException<span style="color: #333333">.</span><span style="color: #0000CC">class</span><span style="color: #333333">)</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">simpleTest</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
List<span style="color: #333333"><</span>Long<span style="color: #333333">></span> longs <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">55L</span><span style="color: #333333">,</span> <span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">100L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">1000L</span><span style="color: #333333">));</span>
<span style="color: #008800; font-weight: bold">for</span> <span style="color: #333333">(</span>Long aLong <span style="color: #333333">:</span> longs<span style="color: #333333">)</span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>aLong <span style="color: #333333">></span> <span style="color: #0000DD; font-weight: bold">50L</span> <span style="color: #333333">||</span> aLong <span style="color: #333333"><</span> <span style="color: #0000DD; font-weight: bold">0L</span><span style="color: #333333">)</span> <span style="color: #333333">{</span>
longs<span style="color: #333333">.</span><span style="color: #0000CC">remove</span><span style="color: #333333">(</span>aLong<span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #333333">}</span>
assertThat<span style="color: #333333">(</span>longs<span style="color: #333333">).</span><span style="color: #0000CC">isEqualTo</span><span style="color: #333333">(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">));</span>
<span style="color: #333333">}</span>
</pre></div>
<p>Nowadays, we can use the forEach method on a collection, turning it into something like this with exactly the same problem:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #555555; font-weight: bold">@Test</span><span style="color: #333333">(</span>expectedExceptions <span style="color: #333333">=</span> ConcurrentModificationException<span style="color: #333333">.</span><span style="color: #0000CC">class</span><span style="color: #333333">)</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">forEachTest</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
List<span style="color: #333333"><</span>Long<span style="color: #333333">></span> longs <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">55L</span><span style="color: #333333">,</span> <span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">100L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">1000L</span><span style="color: #333333">));</span>
longs<span style="color: #333333">.</span><span style="color: #0000CC">forEach</span><span style="color: #333333">(</span>t <span style="color: #333333">-></span> <span style="color: #333333">{</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #333333">(</span>t <span style="color: #333333">></span> <span style="color: #0000DD; font-weight: bold">50L</span> <span style="color: #333333">||</span> t <span style="color: #333333"><</span> <span style="color: #0000DD; font-weight: bold">0L</span><span style="color: #333333">)</span> <span style="color: #333333">{</span>
longs<span style="color: #333333">.</span><span style="color: #0000CC">remove</span><span style="color: #333333">(</span>t<span style="color: #333333">);</span>
<span style="color: #333333">}</span>
<span style="color: #333333">});</span>
assertThat<span style="color: #333333">(</span>longs<span style="color: #333333">).</span><span style="color: #0000CC">isEqualTo</span><span style="color: #333333">(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">));</span>
<span style="color: #333333">}</span>
</pre></div>
<p>If you are using a stream, the same problem occurs, as the stream refers to the underlying collection:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #555555; font-weight: bold">@Test</span><span style="color: #333333">(</span>expectedExceptions <span style="color: #333333">=</span> ConcurrentModificationException<span style="color: #333333">.</span><span style="color: #0000CC">class</span><span style="color: #333333">)</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">streamTest</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
List<span style="color: #333333"><</span>Long<span style="color: #333333">></span> longs <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">55L</span><span style="color: #333333">,</span> <span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">100L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">1000L</span><span style="color: #333333">));</span>
longs<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">Objects:</span><span style="color: #333333">:</span>nonNull<span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>t <span style="color: #333333">-></span> t <span style="color: #333333">></span> <span style="color: #0000DD; font-weight: bold">50L</span> <span style="color: #333333">||</span> t <span style="color: #333333"><</span> <span style="color: #0000DD; font-weight: bold">0L</span><span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">forEach</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">longs:</span><span style="color: #333333">:</span>remove<span style="color: #333333">);</span>
assertThat<span style="color: #333333">(</span>longs<span style="color: #333333">).</span><span style="color: #0000CC">isEqualTo</span><span style="color: #333333">(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">));</span>
<span style="color: #333333">}</span>
</pre></div>
<p>One way, though admittedly not a great way, to fix this, is to transfer it to a list first. Like so:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #555555; font-weight: bold">@Test</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">streamWithToListTest</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
List<span style="color: #333333"><</span>Long<span style="color: #333333">></span> longs <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">55L</span><span style="color: #333333">,</span> <span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">100L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">1000L</span><span style="color: #333333">));</span>
longs<span style="color: #333333">.</span><span style="color: #0000CC">stream</span><span style="color: #333333">()</span>
<span style="color: #333333">.</span><span style="color: #0000CC">filter</span><span style="color: #333333">(</span>t <span style="color: #333333">-></span> t <span style="color: #333333">></span> <span style="color: #0000DD; font-weight: bold">50L</span> <span style="color: #333333">||</span> t <span style="color: #333333"><</span> <span style="color: #0000DD; font-weight: bold">0L</span><span style="color: #333333">)</span>
<span style="color: #333333">.</span><span style="color: #0000CC">collect</span><span style="color: #333333">(</span>Collectors<span style="color: #333333">.</span><span style="color: #0000CC">toList</span><span style="color: #333333">())</span>
<span style="color: #333333">.</span><span style="color: #0000CC">forEach</span><span style="color: #333333">(</span><span style="color: #997700; font-weight: bold">longs:</span><span style="color: #333333">:</span>remove<span style="color: #333333">);</span>
assertThat<span style="color: #333333">(</span>longs<span style="color: #333333">).</span><span style="color: #0000CC">isEqualTo</span><span style="color: #333333">(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">));</span>
<span style="color: #333333">}</span>
</pre></div>
<p>But my colleague at work mentioned the new removeIf function, which seems to work particularly well:</p>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> <span style="color: #555555; font-weight: bold">@Test</span>
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #333399; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">removeIfTest</span><span style="color: #333333">()</span> <span style="color: #333333">{</span>
List<span style="color: #333333"><</span>Long<span style="color: #333333">></span> longs <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> ArrayList<span style="color: #333333"><>(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">55L</span><span style="color: #333333">,</span> <span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">100L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">1000L</span><span style="color: #333333">));</span>
longs<span style="color: #333333">.</span><span style="color: #0000CC">removeIf</span><span style="color: #333333">(</span>t <span style="color: #333333">-></span> t <span style="color: #333333">></span> <span style="color: #0000DD; font-weight: bold">50L</span> <span style="color: #333333">||</span> t <span style="color: #333333"><</span> <span style="color: #0000DD; font-weight: bold">0L</span><span style="color: #333333">);</span>
assertThat<span style="color: #333333">(</span>longs<span style="color: #333333">).</span><span style="color: #0000CC">isEqualTo</span><span style="color: #333333">(</span>List<span style="color: #333333">.</span><span style="color: #0000CC">of</span><span style="color: #333333">(</span><span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">13L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">16L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">20L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">12L</span><span style="color: #333333">,</span> <span style="color: #0000DD; font-weight: bold">5L</span><span style="color: #333333">));</span>
<span style="color: #333333">}</span>
</pre></div>
<p>Of course, the whole thing is patently ridiculous, because you might as well just filter unwanted elements out of the stream and create a new list from it.</p>
<p>But in some cases, where the "remove" is not as simple as chucking an element out of a collection (for example something as involved as, oh, I don't know, <tt>ImportantRestService.removeItem(Item item)</tt>), one has to find other ways to deal with it, which is where the second-to-last solution might come in handy.</p>
<p>I don't know. I'm open to suggestions.</p>Turbohttp://www.blogger.com/profile/05959847299811800007noreply@blogger.com0