<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Enrique Zamudio</title>
    <description>The latest articles on DEV Community by Enrique Zamudio (@chochos).</description>
    <link>https://dev.to/chochos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F27611%2F3ac298bd-0d21-4027-b031-454374886e65.jpg</url>
      <title>DEV Community: Enrique Zamudio</title>
      <link>https://dev.to/chochos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chochos"/>
    <language>en</language>
    <item>
      <title>j8583 version 2.0</title>
      <dc:creator>Enrique Zamudio</dc:creator>
      <pubDate>Tue, 29 Nov 2022 05:43:15 +0000</pubDate>
      <link>https://dev.to/chochos/j8583-version-20-3ja2</link>
      <guid>https://dev.to/chochos/j8583-version-20-3ja2</guid>
      <description>&lt;p&gt;It's been a long time since I've done any work on the j8583 library. Mostly because it works, but I have received requests for improvements, which I haven't worked on because I just don't have the time for it.&lt;/p&gt;

&lt;p&gt;But, I think it's high time for a major release. Version 2.0 of j8583 will contain the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First and foremost, Java 8. Or, more likely, Java 11. I mean, Java 7's been dead for a while, and while I understand that Enterprise environments are not using the most recent Java versions, I think even 8 is really old now.&lt;/li&gt;
&lt;li&gt;What does it mean to use Java 8? Well, CustomEncoder and CustomDecoder can now be functional interfaces. IsoMessage can have accessors for fields and values that return an Optional, and, most importantly...&lt;/li&gt;
&lt;li&gt;Support for the new Java Date/Time API. The fields of type DATEx, DATE_EXP and TIME should use the new classes such as LocalDate, ZonedDateTime and OffsetTime. Obviously backwards compatibility with the old Date API needs to be maintained, so support will have to be programmatically enabled at first.&lt;/li&gt;
&lt;li&gt;Internally, upgrade to junit 5 and Gradle 7.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If things go well, the release might be ready before the year ends.&lt;/p&gt;

</description>
      <category>j8583</category>
      <category>iso8583</category>
    </item>
    <item>
      <title>Useful comments in your code</title>
      <dc:creator>Enrique Zamudio</dc:creator>
      <pubDate>Thu, 10 Dec 2020 10:10:42 +0000</pubDate>
      <link>https://dev.to/chochos/useful-comments-in-your-code-4n2a</link>
      <guid>https://dev.to/chochos/useful-comments-in-your-code-4n2a</guid>
      <description>&lt;p&gt;It's your first day at your new job. You get assigned a task from the backlog, which requires you to read tons of code so you can fix a small bug and therefore is an excellent way to become familiar with the codebase.&lt;/p&gt;

&lt;p&gt;The bug is somewhere in the gardening subsystem, so you start looking at the code gardening modules.&lt;/p&gt;

&lt;p&gt;You run into this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** The model for flowers */&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;FlowerModel&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And also this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** Represents a flower */&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Flower&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You keep digging and find out that the codebase is full of these self-referential useless pseudo-tautologies, which tell you absolutely nothing.&lt;/p&gt;

&lt;p&gt;Wouldn't you find this infuriating if it happened to you? And yet, so many people do this. If you look at the git log for those files, you can probably glimpse a story more or less like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Code was committed with zero comments.&lt;/li&gt;
&lt;li&gt;Reviewer asked for javadoc.&lt;/li&gt;
&lt;li&gt;These comments were  begrudgingly added.&lt;/li&gt;
&lt;li&gt;Reviewer didn't care enough to ask for real, useful documentation and they were all in a hurry to deploy this so it was considered acceptable, or a promise was made to properly document that code later and of course that day never came.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Another possibility is that the comments were added like that from the start, maybe as a placeholder to add real documentation later. Maybe the person didn't even write those; they could have very well been generated by a plugin. &lt;/p&gt;

&lt;p&gt;In any case, it's clear nobody thought of the person who would have to read this code for the first time, three years later, maybe even on their first day. It doesn't really tell them anything: what are flowers for? Where are they used? Why are they necessary?&lt;/p&gt;

&lt;p&gt;So this person is now forced to go asking around a bunch of people, starting with the ones that git blame shows, and is keeps getting redirected to someone else until they finally ask someone who goes &lt;em&gt;oooooooh, yeah, I remember that thing, wow, it was back when...&lt;/em&gt; and gets all starry eyed and tells a long story about how things were done back in the day, and it's probably very enlightening, but by now it's taken the better part of someone's day, when a simple paragraph describing the &lt;em&gt;reason d'etre&lt;/em&gt; of the flower would have taken the writer less than an hour and the reader just a minute.&lt;/p&gt;

&lt;p&gt;So, be mindful when documenting your code. Java programmers have at our disposal this nifty feature called &lt;strong&gt;Javadoc&lt;/strong&gt; which allows us to add references to other declarations and other metadata. Even if you never generate actual docs from it, it's extremely useful when navigating code because IDEs can render javadoc on the fly, showing readers very useful information that saves a lot of time because they don't have to dive into other files all the time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** The contract for a component that
 * handles the storage of flowers.
 *
 * @see Flower
 */&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;FlowerModel&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/** Inserts a new flower into the database.
     * Expects the flower to have no ID yet, and will assign a new one to it.
     * @param flower A new flower with no ID.
     * @throws DuplicateKeyException if a similar flower already exists
     *         (flowers are considered identical if they have the same scientific name)
     */&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Nonnull&lt;/span&gt; &lt;span class="nc"&gt;Flower&lt;/span&gt; &lt;span class="n"&gt;flower&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/** Creates a group of flowers of the same kind.
     * @param flower The kind of flower to use
     * @param count How many flowers are included in the bouquet.
     * @returns A bouquet, which is a group of flowers of the same kind.
     * @throws IllegalArgumentException if count of less than 1.
     */&lt;/span&gt;
    &lt;span class="nc"&gt;Bouquet&lt;/span&gt; &lt;span class="nf"&gt;arrange&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Nonnull&lt;/span&gt; &lt;span class="nc"&gt;Flower&lt;/span&gt; &lt;span class="n"&gt;flower&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ever heard that old saying about writing code as if a dangerous psychopath who knows where you live is going to read it five years from now? Well it applies for documentation too. But instead of writing out of fear, document your code out of empathy. Your future self will thank you when you go back to that code after a couple of years, and when the new hire documents their code properly too because they saw yours and took it as an example.&lt;/p&gt;

</description>
      <category>documentation</category>
    </item>
    <item>
      <title>Database Views vs Table Functions</title>
      <dc:creator>Enrique Zamudio</dc:creator>
      <pubDate>Mon, 22 Jul 2019 20:27:50 +0000</pubDate>
      <link>https://dev.to/chochos/database-views-vs-table-functions-2npm</link>
      <guid>https://dev.to/chochos/database-views-vs-table-functions-2npm</guid>
      <description>&lt;p&gt;Views are a very useful feature of relational databases. You can define a complex query and store it as a view, and then query that view as if it were a table.&lt;/p&gt;

&lt;p&gt;I have a complex query involving a join across 4 tables. That's a lot of columns. So I created a view to simplify things, and it works beautifully. Except, one day we had to change the type of a column, because we had screwed up, and it required us to drop the view. The situation is similar to this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--A simple table as an example
CREATE TABLE example(
  table_id BIGSERIAL PRIMARY KEY,
  created  TIMESTAMP,
  other_stuff VARCHAR(20)
);

--An example of a view, as a simple query to the table
CREATE VIEW example_view AS SELECT * FROM example;

--If we try to modify the table, we get an error
ALTER TABLE example ALTER COLUMN created TYPE TIMESTAMP WITH TIME ZONE;

--We need to drop the view so we can modify the table
DROP VIEW example_view;

--Then we can alter it
ALTER TABLE example ALTER COLUMN created TYPE TIMESTAMP WITH TIME ZONE;

--Finally, re-create the view
CREATE VIEW example_view AS SELECT * FROM example;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In my case, the table we need to modify had over 8 million rows, so the &lt;code&gt;ALTER TABLE&lt;/code&gt; command took several seconds to run, during which there was no view, so all functionality that depended on that view had to be taken offline.&lt;/p&gt;

&lt;p&gt;After altering the table, creating the view takes no time at all, but the downtime during the table modification was an inconvenience I wanted to eliminate. So I started looking for alternatives.&lt;/p&gt;

&lt;h3&gt;
  
  
  Table Functions
&lt;/h3&gt;

&lt;p&gt;Reading the PostgreSQL documentation I came across &lt;em&gt;table functions&lt;/em&gt;. These are functions that return a table-like structure and you can query them as you would query a table. Following the previous example, we can create a table function instead of the view like so:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE FUNCTION example_function()
  --The return type must include column names and types, like a table definition
  RETURNS TABLE(table_id BIGINT, created TIMESTAMP, other_stuff VARCHAR) AS
$$
BEGIN
  RETURN QUERY SELECT * FROM example;
END
$$
language plpgsql;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And then we can query it like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM example_function();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If we later decide to alter the table, we can do so without getting an error. &lt;strong&gt;But&lt;/strong&gt;, next time we query the table function we &lt;strong&gt;will&lt;/strong&gt; get an error, because the table structure no longer matches the return type of the function. So we still have a problem in which queries stop working after altering a table.&lt;/p&gt;

&lt;h3&gt;
  
  
  A bit of metaprogramming
&lt;/h3&gt;

&lt;p&gt;One approach to solve this is with a bit of metaprogramming. Instead of directly creating the table function, we can create a function to create the table function, dynamically defining the return type from the metadata of the table. This way, when we alter the table, we can simply run the generator function again and the table function will be updated with the new table metadata. It's something like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE FUNCTION create_table_function() RETURNS INT AS
$META$
DECLARE
  columns TEXT;
  cmd     TEXT;
BEGIN
  --Here we create a string with all the column names and their types
  --separated by commas, to use as the return type of the function
  SELECT (SELECT STRING_AGG(column_name || ' ' || data_type, ', ')
    from information_schema.columns where table_name = 'example'
    group by table_name) INTO columns;

  --Here we create the whole function definition
  SELECT 'CREATE FUNCTION example_function() RETURNS TABLE(' ||
    columns || ') AS $$ BEGIN ' ||
    'RETURN QUERY SELECT * FROM example; END ' ||
    '$$ language plpgsql;'
    INTO cmd;
  --First we need to drop the function, because we can't replace
  --an existing one due to the different return type
  DROP FUNCTION IF EXISTS example_function();
  EXECUTE cmd;
  RETURN 1;
END
$META$
language plpgsql;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The function above creates the command to create &lt;code&gt;example_function&lt;/code&gt;, constructing the return type from the &lt;code&gt;example&lt;/code&gt; table metadata. When we call this generator function, it will create the table function we need. So after altering the table, we only need to call this again and the table function will be updated instantly. Well, &lt;em&gt;almost&lt;/em&gt; instantly.&lt;/p&gt;

&lt;p&gt;There is still a minor problem: what if someone alters a column from a table used by our table function, and forgets to regenerate the table function itself? A lot of errors will start to occur. One workaround for this is to make the query performed by the table function cast every column to the type defined in the function's return type. This requires some tweaking to the table function, again using the table's metadata:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE FUNCTION create_table_function() RETURNS INT AS
$META$
DECLARE
  columns TEXT;
  query   TEXT;
  cmd     TEXT;
BEGIN
  --This remains the same
  SELECT (SELECT STRING_AGG(column_name || ' ' || data_type, ', ')
    from information_schema.columns where table_name = 'example'
    group by table_name) INTO columns;

  --Now we create a string with each column, casting it to the type
  --it currently has, so it always matches the return type of the function
  SELECT (SELECT STRING_AGG('CAST(example.' || column_name || ' AS ' || data_type, '), ')
    from information_schema.columns where table_name = 'foo'
    group by table_name) INTO query;

  --we create the function with the new query
  SELECT 'CREATE FUNCTION example_function() RETURNS TABLE(' ||
    columns || ') AS $$ BEGIN ' ||
    --we need a closing parens because of the way STRING_AGG works
    'RETURN QUERY SELECT ' || query || ') FROM example;' ||
    'END $$ language plpgsql;'
    INTO cmd;
  DROP FUNCTION IF EXISTS example_function();
  EXECUTE cmd;
  RETURN 1;
END
$META$
language plpgsql;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Because every column is cast to the data type that the table had when the table function was created, altering one of these columns does not affect the function's return type, so now the function is not affected at all by the modification (except if you drop a column from the table, but this is also a problem with views). The table function can be updated later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Everything's a trade-off
&lt;/h3&gt;

&lt;p&gt;Of course there are disadvantages to this approach. The most evident one is the clunkiness of creating the table function dynamically, compared to the simplicity of creating a view.&lt;/p&gt;

&lt;p&gt;A big disadvantage however, is that you can't index table functions; the only way I've found around this limitation is to have one function per query, or add parameters to your function so it can perform different queries depending on the arguments passed to it.&lt;/p&gt;

&lt;p&gt;In any case, altering the types of table columns is not something you should be doing often. The most common case is extending VARCHAR columns, which would not affect the table function (but it can affect a view, so this is yet another advantage of table functions vs views).&lt;/p&gt;

&lt;p&gt;I'm not trying to advocate for table functions instead of views for every case, but I think this is a very useful trick to have at hand if you find yourself in a situation where you need to alter a table that's involved in a view and need to do something to minimize downtime.&lt;/p&gt;

</description>
      <category>database</category>
      <category>postgres</category>
      <category>metaprogramming</category>
    </item>
    <item>
      <title>Streaming large queries in Java</title>
      <dc:creator>Enrique Zamudio</dc:creator>
      <pubDate>Thu, 15 Nov 2018 18:29:28 +0000</pubDate>
      <link>https://dev.to/chochos/streaming-large-queries-in-java-3c9d</link>
      <guid>https://dev.to/chochos/streaming-large-queries-in-java-3c9d</guid>
      <description>&lt;p&gt;I've been using the &lt;code&gt;JdbcTemplate&lt;/code&gt; class since version 1.0, and it's evolved nicely, but I was hoping that for version 5 it would include some streaming capabilities for queries with large results. Alas, that didn't happen.&lt;/p&gt;

&lt;p&gt;Still, sometimes I need to perform queries that return millions of rows, and I can't use the JdbcTemplate methods that return lists for it. A &lt;code&gt;RowCallbackHandler&lt;/code&gt; is perfect for it, but it would so much nicer to just receive a Stream, wouldn't it? Especially if you have custom RowMappers...&lt;/p&gt;

&lt;p&gt;So, I decided to write my own Stream generator to use with a JdbcTemplate. In the process, I ended up creating a more generic Stream generator, which I think is good, and so I want to share it with anyone who needs something similar. I don't think it's enough material for a library, though, so I decided to write a post about it instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  The challenge
&lt;/h2&gt;

&lt;p&gt;First of all, we need to consider that streams are lazy, and when you get a stream and define the operations to be done on it, nothing is happening yet, until you realize a final operation, which needs to actually traverse the elements and apply the operations on it. There are operations which go through the entire stream (such as count, or collecting the elements into another collections), and there are short-circuit operations (such as determining if any element passes some filter).&lt;/p&gt;

&lt;p&gt;So we want to get a stream, and define operations on it, and nothing happens, up until the moment when the stream needs to be traverse, &lt;em&gt;then&lt;/em&gt; the query needs to be run (which implies having an open connection to the database). If something bad happens, the query needs to stop (and JdbcTemplate will take care of cleaning up the connection and other resources).&lt;/p&gt;

&lt;p&gt;The only way I found I could make this work is by using two threads: a producer thread in which the query is run and the rows are somehow fed to the stream, and a consumer thread which is the reader of the stream.&lt;/p&gt;

&lt;p&gt;We will need a buffer in which the producer will store elements and from which the consumer will take elements from. A LinkedBlockingQueue seems perfect for this.&lt;/p&gt;

&lt;p&gt;So, without further ado, here it is:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;streamForQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;bufferSize&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;endOfStreamMarker&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                                               &lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;LinkedBlockingQueue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LinkedBlockingQueue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;bufferSize&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;//This is the consumer that is usually passed to queries;&lt;/span&gt;
        &lt;span class="c1"&gt;//it will receive each item from the query and put it in the queue&lt;/span&gt;
        &lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;filler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;//Try to add to the queue, waiting up to 1 second&lt;/span&gt;
                &lt;span class="c1"&gt;//Honestly if after 1 second the queue is still full, either the stream consumer&lt;/span&gt;
                &lt;span class="c1"&gt;//needs some serious optimization or, more likely, a short-circuit terminal&lt;/span&gt;
                &lt;span class="c1"&gt;//operation was performed on the stream.&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;offer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SECONDS&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;//If the queue is full after 1 second, time out.&lt;/span&gt;
                    &lt;span class="c1"&gt;//Throw an exception to stop the producer queue.&lt;/span&gt;
                    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Timeoud waiting to feed elements to stream"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BufferOverflowException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Interrupted trying to add item to stream"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;};&lt;/span&gt;
        &lt;span class="c1"&gt;//For the stream that we return, we use a Spliterator.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;StreamSupport&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Spliterators&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;AbstractSpliterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MAX_VALUE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Spliterator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ORDERED&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//We need to know if the producer thread has been started&lt;/span&gt;
            &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;started&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;//If there's an exception in the producer, keep it here&lt;/span&gt;
            &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;volatile&lt;/span&gt; &lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="n"&gt;boom&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="cm"&gt;/** This method is called once, before advancing to the first element.
             * It will start the producer thread, which runs the query, passing it our
             * queue filler.
             */&lt;/span&gt;
            &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;startProducer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;//Get the consumer thread&lt;/span&gt;
                &lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;interruptMe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="c1"&gt;//First time this is called it will run the query in a separate thread&lt;/span&gt;
                &lt;span class="c1"&gt;//This is the producer thread&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="c1"&gt;//Run the query, with our special consumer&lt;/span&gt;
                        &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filler&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BufferOverflowException&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="c1"&gt;//The filler threw this, means the queue is not being consumed fast enough&lt;/span&gt;
                        &lt;span class="c1"&gt;//(or, more likely, not at all)&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="n"&gt;thr&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="c1"&gt;//Something bad happened, store the exception and interrupt the reader&lt;/span&gt;
                        &lt;span class="n"&gt;boom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thr&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                        &lt;span class="n"&gt;interruptMe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;interrupt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;}).&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;started&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="nd"&gt;@Override&lt;/span&gt;
            &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;tryAdvance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;super&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;started&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;startProducer&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;//Take an item from the queue and if it's not the end of stream maker, pass it&lt;/span&gt;
                    &lt;span class="c1"&gt;//to the action consumer.&lt;/span&gt;
                    &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;take&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;endOfStreamMarker&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boom&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Interrupted reading from stream"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="c1"&gt;//Throw the exception from the producer on the consumer side&lt;/span&gt;
                        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boom&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="nc"&gt;Spliterator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IMMUTABLE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And this is how you use it, with a JdbcTemplate:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;MyRow&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyRow&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyRow&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;streamForQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//Pass a RowCallbackHandler that passes a MyRow to the callback&lt;/span&gt;
    &lt;span class="n"&gt;jdbcTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM really_big_table_with_millions_of_rows"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myRowMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapRow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;//Pass the marker to the callback, to signal end of stream&lt;/span&gt;
    &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At this point, the query hasn't been performed. You can do stuff such as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stream = stream.filter(row -&amp;gt; row.isPretty());&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And still nothing happens. When you do something like this though:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Optional&amp;lt;MyRow&amp;gt; row = stream.skip(100_000).limit(1000).findAny();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then the query is executed, the first hundred thousand rows will be read (and skipped), and each row will be passed through the filter, until one is pretty or a thousand rows have been read.&lt;/p&gt;

&lt;h2&gt;
  
  
  With great power...
&lt;/h2&gt;

&lt;p&gt;Please, please, PLEASE don't use this as a substitute for a good WHERE clause and properly indexing your tables. I've used this thing mainly to generate reports, concatenating streams of disjoint types by mapping the elements to a common type for further processing (basically, making up for the lack of union types in Java).&lt;/p&gt;

&lt;p&gt;Having said that, it is pretty cool to be able to read rows from a database in a streaming fashion.&lt;br&gt;
I guess this could be integrated into Spring's JdbcTemplate, and/or jOOQ...&lt;/p&gt;

</description>
      <category>java</category>
      <category>jdbc</category>
      <category>spring</category>
      <category>javastreams</category>
    </item>
    <item>
      <title>I hate checked exceptions</title>
      <dc:creator>Enrique Zamudio</dc:creator>
      <pubDate>Fri, 10 Aug 2018 06:15:43 +0000</pubDate>
      <link>https://dev.to/chochos/i-hate-checked-exceptions-43lj</link>
      <guid>https://dev.to/chochos/i-hate-checked-exceptions-43lj</guid>
      <description>&lt;p&gt;I hate checked exceptions. I really do. They should have really got rid of them in Java 8. They get in the way of a lot of the new stuff; it's not a coincidence that most of the other JVM languages don't have checked exceptions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BEGIN RANT&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I have a class in which I'm overriding an abstract method:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="nf"&gt;createTask&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CANT_CONNECT&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Something&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;oneThing&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Doing something with {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SomethingElse&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;somethingElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"doing something else with {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;YetAnotherThing&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;anotherThing&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Doing yet another thing with {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, it's very repetitive. A block is code is basically repeated 3 times with just a very small variation. An obvious opportunity to put it elsewhere, right? Something like this looks way nicer:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BiConsumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Errores&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CANT_CONNECT&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="nf"&gt;createTask&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Something&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;ejecutar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;oneThing&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Doing something with {}"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SomethingElse&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;ejecutar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;somethingElse&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"doing something else with {}"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;YetAnotherThing&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;ejecutar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;anotherThing&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Doing yet another thing with {}"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Way nicer. Yeah.&lt;/p&gt;

&lt;p&gt;Except I can't do this. Why not? Well, &lt;code&gt;BiConsumer&lt;/code&gt; doesn't throw &lt;code&gt;IOException&lt;/code&gt;, therefore I can't catch it. Also, I can't pass refs to my methods because they throw &lt;code&gt;IOException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to do this, I need to catch &lt;code&gt;IOException&lt;/code&gt; inside &lt;em&gt;each&lt;/em&gt; of my methods, only to convert it into a &lt;code&gt;RuntimeException&lt;/code&gt;, which I can then catch in &lt;code&gt;execute&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I really don't want to do that right now. So... ⌘+Z ⌘+Z ⌘+Z ⌘+Z ⌘+Z ⌘+Z ⌘+Z ⌘+Z ⌘+Z ⌘+Z&lt;/p&gt;

&lt;p&gt;&lt;code&gt;END RANT&lt;/code&gt;&lt;/p&gt;

</description>
      <category>javaexceptions</category>
    </item>
    <item>
      <title>ebooks: Valid use case for blockchain?</title>
      <dc:creator>Enrique Zamudio</dc:creator>
      <pubDate>Mon, 27 Nov 2017 22:56:30 +0000</pubDate>
      <link>https://dev.to/chochos/ebooks-valid-use-case-for-blockchain-11o</link>
      <guid>https://dev.to/chochos/ebooks-valid-use-case-for-blockchain-11o</guid>
      <description>&lt;p&gt;I've seen ideas thrown around about &lt;em&gt;X but on the blockchain&lt;/em&gt; and they usually are overengineered, buzzword-driven things that could easily be solved with digital signatures in a regular, central database. I've heard of very few examples of problems that really require the blockchain.&lt;/p&gt;

&lt;p&gt;Then a few days ago, while on a layover between 2 long flights, a thought popped into my mind: Using the blockchain for validating ebooks.&lt;/p&gt;

&lt;p&gt;When it comes to books, I still prefer the paper versions over electronic ones. I don't even own a Kindle. I have bought very few ebooks, and all of them have been technical. And the main reason for this is that I don't trust that system. I clearly remember a debacle with Amazon some years ago when they deleted copies of &lt;em&gt;1984&lt;/em&gt; from a lot of devices without permission from the users. And it's known that the books you have on these devices can be updated without your consent, which is great for fixing typos but it's got some real potential for Ministry of Truth style revisionist editing. I'd rather have typos any day of the week.&lt;/p&gt;

&lt;p&gt;The solution to this, however, is rather simple: Just have a hash of the book handy. Maybe you can calculate it yourself when you download the book, and check it periodically. That way you can be sure it hasn't been edited without your knowledge; but what if it was somehow edited right before you download it?&lt;/p&gt;

&lt;p&gt;So, it may be better to have these hashes available online. A simple database where you lookup by ISBN and get a hash, and you can compare it to the one you just calculated. Simple.&lt;/p&gt;

&lt;p&gt;But, who's in charge of this database? It needs to be either someone I trust, or someone I don't &lt;em&gt;need&lt;/em&gt; to trust. So: Blockchain! A decentralized database with all the hashes of ebooks everywhere. Of course, it needs to be work a bit different from the ones I'm familiar with, which are for cryptocurrencies. My first idea is this: when you get an ebook, you get its hash and then send it along with the ISBN to this blockchain. A lookup will be done first, and if it's there, you get back the hash that's already stored there, and you can see if it maches. Otherwise, your submission is kept in a pool, until you get X number of similar submissions (by ISBN). If the hashes in all these submissions match, then it's added in the next block. If a small number of submissions don't match, they get discarded. If there seems to be no consensus at all (lots of different hashes with no significant majority), then all get discarded, and maybe the ISBN is flagged for good measure.&lt;/p&gt;

&lt;p&gt;Now, who makes the blocks? That's always the tricky part. And the problem is, we usually ask the wrong question. Because the answer to "but who makes the blocks?" should &lt;em&gt;always&lt;/em&gt; be: &lt;strong&gt;anybody&lt;/strong&gt;. Same goes for "but who can send transactions?" (or, in this specific case, "but who can submit ISBN+hash?")&lt;/p&gt;

&lt;p&gt;With any cryptocurrency, you can just download the software and become a node in that blockchain. Same here: anybody should be able to run a node for this blockchain. So the question, then, is: &lt;em&gt;Why&lt;/em&gt; would anyone want to run this node? What incentive do they have to do this?&lt;/p&gt;

&lt;p&gt;And here's where I ran out of ideas. I don't know the answer to this. Bookstores, maybe... Publishing houses? Even authors might have a vested interest in this. And there's also the detail of &lt;em&gt;how&lt;/em&gt; blocks are created. Proof of Work? Proof of Stake? Is there a cost to submitting ISBN+hashes?&lt;/p&gt;

&lt;p&gt;I don't know. Maybe I was just too jetlagged and this seemed like a good idea. But it's been 4 days since that, and at least it doesn't sound &lt;em&gt;completely&lt;/em&gt; bogus. What do you think?&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ebooks</category>
      <category>books</category>
      <category>epub</category>
    </item>
  </channel>
</rss>
