<?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: Martin Häusler</title>
    <description>The latest articles on DEV Community by Martin Häusler (@martinhaeusler).</description>
    <link>https://dev.to/martinhaeusler</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%2F40726%2F024ebce7-5fed-4a0e-8f58-179cf576aeb6.jpg</url>
      <title>DEV Community: Martin Häusler</title>
      <link>https://dev.to/martinhaeusler</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/martinhaeusler"/>
    <language>en</language>
    <item>
      <title>LSM4K 1.0.0-Alpha released</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Sun, 08 Jun 2025 10:26:22 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/lsm4k-100-alpha-released-2lhe</link>
      <guid>https://dev.to/martinhaeusler/lsm4k-100-alpha-released-2lhe</guid>
      <description>&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;I'm proud to announce the 1.0.0-alpha release of LSM4K, my transactional Key-Value Store based on the Log Structured Merge Tree algorithm. I've been working on this project in my free time for well over a year now (on and off).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MartinHaeusler/LSM4K" rel="noopener noreferrer"&gt;https://github.com/MartinHaeusler/LSM4K&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Executive Summary:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full LSM Tree implementation written in Kotlin, but usable by any JVM language&lt;/li&gt;
&lt;li&gt;Leveled or Tiered Compaction, selectable globally and overridable on a per-store basis&lt;/li&gt;
&lt;li&gt;ACID Transactions: Read-Only, Read-Write and Exclusive Transactions&lt;/li&gt;
&lt;li&gt;WAL support based on redo-only logs&lt;/li&gt;
&lt;li&gt;Compression out-of-the-box&lt;/li&gt;
&lt;li&gt;Support for pluggable compression algorithms&lt;/li&gt;
&lt;li&gt;Manifest support&lt;/li&gt;
&lt;li&gt;Asynchronous prefetching support&lt;/li&gt;
&lt;li&gt;Simple but powerful Cursor API&lt;/li&gt;
&lt;li&gt;On-heap only&lt;/li&gt;
&lt;li&gt;Optional in-memory mode intended for unit testing while maintaining same API&lt;/li&gt;
&lt;li&gt;Highly configurable&lt;/li&gt;
&lt;li&gt;Extensive support for reporting on statistics as well as internal store structure&lt;/li&gt;
&lt;li&gt;Well-documented, clean and unit tested code to the best of my abilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you like the project, leave a star on github. If you find something you don't like, comment here or drop me an issue on github.&lt;/p&gt;

</description>
      <category>database</category>
      <category>kotlin</category>
      <category>jvm</category>
    </item>
    <item>
      <title>Error as Value vs. Exceptions</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Fri, 26 Jul 2024 22:14:00 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/error-as-value-vs-exceptions-3h5c</link>
      <guid>https://dev.to/martinhaeusler/error-as-value-vs-exceptions-3h5c</guid>
      <description>&lt;p&gt;In the last ~20 years, exceptions have been the predominant way to handle errors in programming. Java, C#, C++, Python and many others offer this feature and the concept is pretty similar in all of them. With newer languages like Go and Rust entering the stage, we see the rise of a different way of error handling: errors as values. In this article, we're going to take a closer look at this new paradigm and I'll give you my thoughts on it. Please note that this piece of text is an &lt;em&gt;opinion&lt;/em&gt; and not a universal truth, and it may change over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is "Error as Value"?
&lt;/h2&gt;

&lt;p&gt;The basic idea behind the Error as Value pattern is to return dedicated error values from a function whenever this function encounters an invalid state. Contrary to the exception workflow, Error as Value suggests to return the error as a &lt;strong&gt;result&lt;/strong&gt; of the function. This way, the error becomes part of the function signature, which leads to two major effects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Everyone who is calling the method will see at first glance that it can produce an error&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Everyone who is calling the method will be &lt;strong&gt;forced&lt;/strong&gt; to deal with this potential error situation in their code (languages vary in how strict this is being executed upon)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The implementation details of this pattern vary. For instance, Go functions often return pairs - the first entry of the pair is the actual result (if any) while the second entry is the error which has occurred (if any):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"filename.ext"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// do something with the open *File f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Go compiler will not allow you to have unused variables, so you're forced to check the &lt;code&gt;err&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;In Rust, things are handled a bit differntly, but ultimately to the same effect. Rust has a generic &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; enum which has two concrete implementations: &lt;code&gt;Ok&lt;/code&gt; and &lt;code&gt;Err&lt;/code&gt;. Any function which returns a &lt;code&gt;Result&amp;lt;T,E&amp;gt;&lt;/code&gt; can thus produce an actual result or an error, and the caller has to differentiate between the two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;fileResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;fileResult&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Problem opening the file: {error:?}"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advantages of Error as Value
&lt;/h2&gt;

&lt;p&gt;The proponents of this approach will often cite the following advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Errors become parts of the function signature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The compiler forces the programmer to deal with the errors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Errors as values have superior performance to exceptions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Errors as values provide clearer control flow&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  My thoughts on Error as Value
&lt;/h2&gt;

&lt;p&gt;Please note that everything that follows is my informed opinion as a server side developer and mine alone. It is a hot take, and you may disagree with it violently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Errors should not happen.
&lt;/h3&gt;

&lt;p&gt;The argument that Error as Value is better for performance, while technically true&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, has zero significance in practice to me. If our program ends up in an error state for some reason, we're already disqualified from the performance race, because our program went off the track. There's no reason to optimize for performance in an error state because they should occur rarely to begin with.&lt;/p&gt;

&lt;p&gt;If your program uses errors for regular control flow, you were doing something wrong in the first place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real recoverable errors are a myth.
&lt;/h3&gt;

&lt;p&gt;I've often heard, in different contexts, the distinction between a "recoverable error" and an "unrecoverable error". To me, this has always been weird and artificial. The philosophy in early Java was that checked exceptions are to be used for recoverable errors. By that definition, how is my API request going to recover from an &lt;code&gt;SQLException&lt;/code&gt; which tells me that my commit cannot proceed because it violates a data constraint on the database server? It won't. The best thing we can do is to log it and send it to a central error collector to get the issue fixed by changing the source code. The &lt;em&gt;program&lt;/em&gt; (i.e. the server as a whole) may "recover" (i.e. the error in the processing of the single request doesn't terminate the entire server) but the &lt;em&gt;request&lt;/em&gt; cannot be salvaged at this point. Attempting to deal with an &lt;code&gt;SQLException&lt;/code&gt; on the level of the method which called &lt;code&gt;commit()&lt;/code&gt; is therefore futile, as it has no alternative way to continue.&lt;/p&gt;

&lt;p&gt;Java was the first language to introduce "checked exceptions" which you're forced to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;either declare explicitly in your method signature&lt;/li&gt;
&lt;li&gt;or are forced to &lt;code&gt;catch&lt;/code&gt; and process within the method itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To this day, Java is the &lt;strong&gt;only&lt;/strong&gt; language I know which has this concept. C# didn't inherit it, and even JVM aliens like Groovy and Kotlin ditched it completely. The fact that any modern Java framework or library will also forego checked exceptions in favor of unchecked ones should be enough to tell you: checked exceptions (while nice in research papers and conference talks) turned out to be a really impractical idea.&lt;/p&gt;

&lt;p&gt;For Rust and Go, Error as Value are recommended to be used for "recoverable errors" and panics (which we will discuss later) for unrecoverable errors. Do you see the pattern? It's checked exceptions all over again.&lt;/p&gt;

&lt;h3&gt;
  
  
  The unfailable function fallacy
&lt;/h3&gt;

&lt;p&gt;The Values as Errors methodology encodes errors in function signatures. However, if you look at Go and Rust standard libraries, not all functions in this methodology have errors in their signatures. This implies that there are functions which &lt;strong&gt;cannot fail&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a perfect world, we would be able to write functions which can never fail. However, that is not the case in practice. Consider these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A simple integer addition &lt;code&gt;a + b&lt;/code&gt; can "fail" if the values are sufficiently high enough to exceed the range of representable integers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You're calling another function in your function. This additional call may exceed the maximum stack size of the platform you're running on. This crashes your program, but the function itself did nothing "wrong".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You're sending data over the network, but right in the middle of it, the connection is lost. Maybe you're on a mobile network and entered a zone with bad reception. Maybe somebody physically unplugged the ethernet cable. None of this is the programmer's fault, but it will cause a function in the program to fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You're calling &lt;code&gt;malloc&lt;/code&gt; (every non-trivial program does, one way or another) and the underlying runtime has no memory left for you.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key message here is: your program &lt;em&gt;will&lt;/em&gt; fail, in arbitrary places, for arbitrary reasons, no matter how well-engineered it may be. Outside of academic boundaries, there's no way to protect us from that. How we &lt;em&gt;deal&lt;/em&gt; with these situations is the key question. &lt;/p&gt;

&lt;p&gt;Going back to Rust and Go, if we're serious about Error as Value, then &lt;strong&gt;every&lt;/strong&gt; function would need to have an error output, from simple arithmetics to database commits over the network. Needless to say, this is enormously impractical (which is why Rust and Go "chicken out" with &lt;em&gt;panics&lt;/em&gt;; we will talk about those in a moment).&lt;/p&gt;

&lt;p&gt;The conclusions I draw from this are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Every&lt;/em&gt; function &lt;em&gt;can&lt;/em&gt; and &lt;em&gt;will fail&lt;/em&gt;, no matter which task it attempts to perform.&lt;/li&gt;
&lt;li&gt;We cannot conceivably enumerate all the different reasons why it failed, and it is futile to try.&lt;/li&gt;
&lt;li&gt;The attempt to encode errors as part of function signatures, while valiant, is impractical and ultimately futile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This eliminates the advantages of "clearer control flow" (it's not) and "including errors in the signature" (you can't, not exhaustively at least).&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't panic
&lt;/h3&gt;

&lt;p&gt;Rust and Go, aside from Error as Values, have another "failure mode", which is called "panic". When a panic occurs, the code exists the normal control flow, exits the current function, exists the calling function, and so on, until the program either terminates as a whole, &lt;strong&gt;or&lt;/strong&gt; (and this is the fun part) it reaches an &lt;strong&gt;error boundary&lt;/strong&gt;. In Rust, that's called &lt;code&gt;catch_unwind&lt;/code&gt;, in Go it's called &lt;code&gt;recover&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If this process of "exiting functions through a different control flow" seems familiar to you, it is because this is &lt;strong&gt;exactly&lt;/strong&gt; how Exceptions behave. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rust and Go have exceptions. They just don't tell you.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To me, that is the point where the entire house of cards with Error as Value collapses under its own weight. This is hypocrisy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The merit of try-catch
&lt;/h2&gt;

&lt;p&gt;Exceptions and &lt;code&gt;try-catch&lt;/code&gt; blocks have a lot of merits which people tend to forget:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they offer a &lt;em&gt;structured&lt;/em&gt; way of handling exceptions&lt;/li&gt;
&lt;li&gt;they represent error boundaries which apply to everything that happens in the &lt;code&gt;try&lt;/code&gt; block, no matter if it's in the same function or way down the call chain&lt;/li&gt;
&lt;li&gt;they free you from dealing with each error in every place individually and centralize error handling to the places where errors can actually meaningfully be dealt with&lt;/li&gt;
&lt;li&gt;they de-clutter control flow for all down-stream functions because they don't need to handle their own exceptions&lt;/li&gt;
&lt;li&gt;exceptions automatically track the place they've occurred in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last point is especially important. Sure, in Rust, you can use the &lt;code&gt;?&lt;/code&gt; operator on any function which returns a &lt;code&gt;Result&amp;lt;T,E&amp;gt;&lt;/code&gt; and it will exit out of the current function if an error is present, otherwise it will give you the plain result. It's cool, but... if you eventually decide to look at an error, you'll have no clue where it came from. Tracking this down can be really hard. Yes, there are ways in Rust to manually attach tracking information to error objects, but at this point I feel Rust is just attempting to fix the problems it created for itself. In Go, to my knowledge there is no such thing. It's &lt;code&gt;if err != nil&lt;/code&gt; galore all the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The true drawbacks of Exceptions
&lt;/h2&gt;

&lt;p&gt;From my point of view, there are a couple of problems with exceptions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Exceptions can be overlooked. The library function you're calling may be throwing an exception, and you're not aware of it as a programmer.&lt;/li&gt;
&lt;li&gt;Nothing forces you to &lt;em&gt;eventually&lt;/em&gt; deal with exceptions.&lt;/li&gt;
&lt;li&gt;Exceptions and &lt;code&gt;try-catch&lt;/code&gt; can be abused for regular control flow.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sure enough, all three of those are tackled by Errors as Values. But to me, it creates more problems than it solves. The issues I've mentioned above are matters of programmer discipline and clean code. I realize that I may sound like a C programmer talking about &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt; when the first garbage collectors were introduced. But Error as Value is so invasive to the code structure that I can't imagine working with it in any serious fashion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error as Value in Kotlin
&lt;/h2&gt;

&lt;p&gt;Kotlin sits somewhere in the middle. It does have exceptions (inherited from Java) but it also has it's own way of doing Error as Value. Consider this method signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toIntOrNull&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The standard library in Kotlin defines a &lt;code&gt;toIntOrNull()&lt;/code&gt; method for &lt;code&gt;String&lt;/code&gt;. It will parse the string, and if it is parseable into an integer, the integer will be returned. Otherwise, &lt;code&gt;null&lt;/code&gt; will be returned. As Kotlin is a &lt;code&gt;null&lt;/code&gt;-safe language, the programmer is &lt;strong&gt;forced&lt;/strong&gt; to handle the &lt;code&gt;null&lt;/code&gt; case separately. This is in a very similar vein as Error as Value, but with the error being restricted to the &lt;code&gt;null&lt;/code&gt; value. The downside is that the error case cannot carry any semantic information (why did the parsing fail? At which position?). The advantage is that it is syntactically very pleasant and very clear. As a developer calling this API, you cannot use it the wrong way (the compiler won't let you) and you cannot forget anything. I've grown rather fond of this approach. One caveat is that it only works for methods which have actual return values, and that &lt;code&gt;null&lt;/code&gt; must not be a "regular" return value for the method (otherwise you can't distinguish between &lt;code&gt;null&lt;/code&gt; as in "whoops that's an error" or &lt;code&gt;null&lt;/code&gt; as a regular non-error return value).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That's all I've got to say today. I hope you've found it interesting, it's just a topic that's been on my mind for quite a while now. And even though I'm fully on the "team exceptions" at the moment, I'm not excluding the possibility that my mind will change in the future if the arguments are compelling enough. And I think we can at least all agree that both solutions are better than &lt;code&gt;&amp;lt;errno.h&amp;gt;&lt;/code&gt; in C.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Exceptions are notoriously slow compared to regular control flow. The main reason for that is that most languages which utilize exceptions include a stack trace in the exception, and collecting this information is costly. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>errors</category>
      <category>exceptions</category>
    </item>
    <item>
      <title>So I tried Rust for the first time.</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Tue, 04 Jun 2024 17:11:42 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/so-i-tried-rust-for-the-first-time-4jdb</link>
      <guid>https://dev.to/martinhaeusler/so-i-tried-rust-for-the-first-time-4jdb</guid>
      <description>&lt;p&gt;In my professional life, I'm at home on the Java Virtual Machine. I started out in Java over 10 years ago, but since around 4 years, I'm programming almost entirely in Kotlin. And while Kotlin serves a lot of different use cases and compilation targets, I've already felt like I need a "native tool" in my tool belt. I can deal with C if I have to, but it feels very dated at this point. And I heard all the buzz about Rust being the most loved programming language out there, so I thought I might take a look and see for myself.&lt;/p&gt;

&lt;p&gt;Here's how that went.&lt;/p&gt;

&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;The installation process was super smooth on my linux machine. I've installed &lt;code&gt;rustup&lt;/code&gt; and let &lt;code&gt;cargo init&lt;/code&gt; do its job; project setup done. I started my Visual Studio Code, got a few plugins, and was hacking away within minutes. I especially love the fact that &lt;code&gt;cargo&lt;/code&gt; is also a built-in dependency management tool. Nice!&lt;/p&gt;

&lt;h1&gt;
  
  
  Advent of Code
&lt;/h1&gt;

&lt;p&gt;Whenever I try a new language, the first thing I throw it at is usually the &lt;a href="https://adventofcode.com/"&gt;Advent of Code&lt;/a&gt;. It is a set of language-agnostic problems which start out very easy and gradually get more difficult; perfect for testing a new language!&lt;/p&gt;

&lt;p&gt;I picked the "Day 1" example of 2023. We're given a textual input file; each line contains digits and characters. We need to find the first and the last digit in each row, convert them into a number (e.g. 8 and 3 turn into 83) and sum them up. After a little bit of tinkering, I ended up with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;INPUT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;include_str!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"inputs/1.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;INPUT&lt;/span&gt;&lt;span class="nf"&gt;.lines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u32&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;line&lt;/span&gt;
            &lt;span class="nf"&gt;.chars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="nf"&gt;.is_numeric&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="nf"&gt;.to_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="nf"&gt;.first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="nf"&gt;.last&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ended up producing the correct result. This may not be idiomatic rust (I have yet to figure out what that is for myself) but it gets the job done. I have a lot of things to say about this little program.&lt;/p&gt;

&lt;h2&gt;
  
  
  include_str!
&lt;/h2&gt;

&lt;p&gt;We're already starting out with a &lt;strong&gt;macro&lt;/strong&gt; on the first line. I'm REALLY not a fan of macros&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, but that's just how Rust rolls I guess. If we look beyond the problems of macros overall, the &lt;code&gt;include_str!&lt;/code&gt; macro is really nice. It includes the text of an input file as a string in the program, and the compiler verifies that the file path is correct and the file exists. This should raise some eyebrows: this macro is doing more than just producing regular Rust code, it talks to the compiler. This pattern of macros opening sneaky paths to compiler intrinsics is going to repeat on our journey. It allows the compiler to provide better error messages, but macros are also really good at hiding what code is actually being executed. At the very least, in Rust all macros are clearly demarcated with a trailing &lt;code&gt;!&lt;/code&gt; in their name so you know where the "magic" is&lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give me a lifetime
&lt;/h2&gt;

&lt;p&gt;Right in our first line we're also hit with the expression &lt;code&gt;&amp;amp;'static&lt;/code&gt;. There are really two things going on here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; means that the type that comes next (&lt;code&gt;str&lt;/code&gt;) is actually a "borrowed" reference. We will dig into this later, for now know that a borrowed thing is immutable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;'static&lt;/code&gt; is a "lifetime specifier". All of these start with a single quote (&lt;code&gt;'&lt;/code&gt;).  Rust is the only language I've ever seen that uses single quotes in a non-pair-wise fashion. And &lt;strong&gt;good lord is it ugly&lt;/strong&gt;! Looking past the syntax, &lt;code&gt;'static&lt;/code&gt; is a special lifetime that means "lives for the entire duration of the program", which makes sense for a constant like this.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  main
&lt;/h2&gt;

&lt;p&gt;The main function declaration is nothing special, aside from the nice fact that you're not forced to accept parameters, nor are you forced to return an integer (looking at you, Java!). &lt;code&gt;fn&lt;/code&gt; is fine as a keyword, but I still prefer Kotlin's &lt;code&gt;fun&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  let mut
&lt;/h2&gt;

&lt;p&gt;Variables are declared with &lt;code&gt;let&lt;/code&gt;, types can optionally be annoated after the name with &lt;code&gt;: SomeType&lt;/code&gt;. Fairly standard, all fine. The keyword &lt;code&gt;mut&lt;/code&gt; allows us to mutate the variable after we've defined it; by default, all &lt;code&gt;let&lt;/code&gt;s are immutable. Kotlin's &lt;code&gt;var&lt;/code&gt; and &lt;code&gt;val&lt;/code&gt; approach is a little more elegant in that regard, but it's fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semicolon!! &lt;code&gt;;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Gods why. That's all I have to say. Why does the darn thing refuse to die? Chalk up another language with mandatory semicolons, they just keep coming.&lt;/p&gt;

&lt;h2&gt;
  
  
  for
&lt;/h2&gt;

&lt;p&gt;Next is our standard "foreach" loop. A noteworthy detail is that there are no round braces &lt;code&gt;( ... )&lt;/code&gt;, which is also true for &lt;code&gt;if&lt;/code&gt; statements. Takes a little time to get used to, but works for me. &lt;code&gt;lines()&lt;/code&gt; splits the text into individual lines for us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Iterators
&lt;/h2&gt;

&lt;p&gt;Next we see &lt;code&gt;chars()&lt;/code&gt; which gives us an iterator over the characters in the current line. Rust actually doesn't differentiate between a lazy &lt;code&gt;Sequence&lt;/code&gt; and a lazy &lt;code&gt;Iterator&lt;/code&gt;, like Kotlin does. So we have all the functional good stuff directly on the &lt;code&gt;Iterator&lt;/code&gt;. We &lt;code&gt;filter&lt;/code&gt; for the numeric characters, we &lt;code&gt;map&lt;/code&gt; them to integers, we &lt;code&gt;collect&lt;/code&gt; the result in a &lt;code&gt;Vec&amp;lt;u32&amp;gt;&lt;/code&gt; (which is roughly comparable to a &lt;code&gt;List&amp;lt;Int&amp;gt;&lt;/code&gt; in kotlin).&lt;/p&gt;

&lt;h2&gt;
  
  
  Lambdas
&lt;/h2&gt;

&lt;p&gt;The lambda syntax in rust is... iffy at best, and a monstrosity at worst. The examples in the &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;map&lt;/code&gt; calls are very basic ones, things can get much worse. Rust actually has lambdas with different semantics (kind of like kotlin's &lt;code&gt;callsInPlace&lt;/code&gt; contract). Sure, these things are there to aid the borrow checker, but I really miss my &lt;code&gt;it&lt;/code&gt; from kotlin. &lt;code&gt;filter { it.isDigit() }&lt;/code&gt; is hard to beat in terms of readability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type Inference... sometimes.
&lt;/h2&gt;

&lt;p&gt;Much like the Kotlin compiler, the Rust compiler is usually pretty clever at figuring out the types of local variables and such so you don't have to type them all the time. Except that my &lt;code&gt;let numbers&lt;/code&gt; absolutely required a manual type annotation for some reason. It's not like &lt;code&gt;collect()&lt;/code&gt; could produce anything else in this example, so I don't really get why.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;EDIT: Esfo pointed out in the comments (thanks!) that &lt;code&gt;collect()&lt;/code&gt; can be used to produce more than just &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; as output. Rust in this case determines the overload of &lt;code&gt;collect()&lt;/code&gt; based on the &lt;strong&gt;expected return type&lt;/strong&gt; - which is wild! I'm not sure if I like it or not.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Unwrap all the things!
&lt;/h2&gt;

&lt;p&gt;You may have noticed the calls to &lt;code&gt;unwrap()&lt;/code&gt;. The method &lt;code&gt;unwrap()&lt;/code&gt; is defined on Rust's &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; type, which can be either an &lt;code&gt;Ok&amp;lt;T&amp;gt;&lt;/code&gt; (success) or an &lt;code&gt;Err&amp;lt;E&amp;gt;&lt;/code&gt; (error). &lt;code&gt;unwrap()&lt;/code&gt; on &lt;code&gt;Ok&lt;/code&gt; simply returns the value, &lt;code&gt;unwrap()&lt;/code&gt; on &lt;code&gt;Err&lt;/code&gt; causes a panic and terminates the whole program with an error message. And no, there is no &lt;code&gt;try{ ... } catch { ... }&lt;/code&gt; in Rust. Once your program panics, there's no turning back. So &lt;code&gt;unwrap()&lt;/code&gt; shouldn't be used in production code. For this simple toy example, I think it's good enough. Later I learned that if you're inside a method that returns a &lt;code&gt;Result&lt;/code&gt;, you can also use &lt;code&gt;?&lt;/code&gt; to propagate the error immediately.&lt;sup id="fnref3"&gt;3&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  print it!
&lt;/h2&gt;

&lt;p&gt;Rust wouldn't be Rust if &lt;code&gt;println&lt;/code&gt; was straight forward, because it really isn't. Right off the bat we see that &lt;code&gt;println!&lt;/code&gt; has an exclamation mark, so it's a macro. And oh boy does it do a lot of magic. Rust doesn't &lt;strong&gt;really&lt;/strong&gt; have string interpolation, so the standard way to print something is &lt;code&gt;println!("foo {} bar", thing)&lt;/code&gt; which will first print &lt;code&gt;foo&lt;/code&gt;, then the &lt;code&gt;thing&lt;/code&gt;, then &lt;code&gt;bar&lt;/code&gt;. That is, provided that &lt;code&gt;thing&lt;/code&gt; is printable, but that's another story. You &lt;strong&gt;could&lt;/strong&gt; also write &lt;code&gt;println!("foo {thing} bar")&lt;/code&gt; which &lt;strong&gt;almost&lt;/strong&gt; looks like string interpolation, but it's really just a feature of the &lt;code&gt;println!&lt;/code&gt; macro. It breaks down quickly, for example when you try to access a field inside the curly brackets. This won't compile: &lt;code&gt;println!("foo {thing.field} bar")&lt;/code&gt;. So while it may &lt;strong&gt;seem&lt;/strong&gt; simple at first glance, it really isn't and it does a whole lot of magic. Kotlin string templates are not without issues (especially if you want a literal &lt;code&gt;$&lt;/code&gt; character in the string) but they are more universal because they allow for arbitrary logic in their placeholders. &lt;/p&gt;

&lt;h1&gt;
  
  
  The Pros and Cons
&lt;/h1&gt;

&lt;p&gt;At this point, it's time for a first verdict.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pro: Tooling is good&lt;/li&gt;
&lt;li&gt;Pro: Compiles natively&lt;/li&gt;
&lt;li&gt;Pro: Memory safe without manual memory management or garbage collector&lt;/li&gt;
&lt;li&gt;Pro: small executables, excellent runtime performance&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pro: Feels "modern"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Con: Syntax. Good lord the syntax.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Con: Macros. No need to explain that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Con: Error handling, or rather the absence thereof&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Con: Enormously steep learning curve with borrowing and lifetimes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Con: Type inference sometimes works, sometimes doesn't&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... and that's just for the first example. I've since performed more extensive experiments with the language, and I'll report about these in another article.&lt;/p&gt;

&lt;p&gt;I can see why system level programmers enjoy Rust. It's certainly a big step up from C. But on a grand scale, compared to the effectiveness and productivity of Kotlin, I can't yet see where Rust's popularity is really coming from.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;As programmers, we already have enough tools at our disposal to shoot ourselves into the foot; macros just add to that danger. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;In C, that's not the case. You can make a macro look like a totally normal function call, but it does arbitrary other things when compiled. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;The Go language should take notes here. &lt;code&gt;if(err != nil) return err&lt;/code&gt; is only funny so many times before it gets really old really fast. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>Is your Kotlin compiler slow? Here's a potential fix</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Mon, 31 Aug 2020 17:30:34 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/is-your-kotlin-compiler-slow-here-s-a-potential-fix-4if4</link>
      <guid>https://dev.to/martinhaeusler/is-your-kotlin-compiler-slow-here-s-a-potential-fix-4if4</guid>
      <description>&lt;p&gt;I'm working at a large Java/Kotlin project at my company. It's several 100k lines of server-side code, with millions more coming in through dependencies. The Kotlin compiler sure has its work cut out for it. But as of late, the team noticed that the compiler was getting slower and slower, even though the project source size wasn't growing nearly at the same rate. Also, builds were consuming an abundance of CPU resources - on all available cores. Build times for a full project build had increased from about 2 minutes to more than 10 minutes. Something was definitely wrong.&lt;/p&gt;

&lt;p&gt;A couple of days ago, the whole bubble burst and it became blatantly clear what was going on:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

java.lang.OutOfMemoryError: GC Overhead Limit Exceeded


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;... coming from a Kotlin compiler class. It turned out that it wasn't &lt;code&gt;kotlinc&lt;/code&gt; itself which was burning our CPU - it was the JVM it was running on, struggling really hard to free memory resources.&lt;/p&gt;

&lt;p&gt;The question obviously was: how do you assign more RAM to the &lt;code&gt;kotlinc&lt;/code&gt; process? Easier said than done.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Setup
&lt;/h1&gt;

&lt;p&gt;Like many other folks out there, we use IntelliJ IDEA to write our source code, which is then handed to Gradle to build it. Nothing too complicated, right? Well, if we take a closer look, this is what &lt;em&gt;actually&lt;/em&gt; happens...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fusquhe8knewlkp1t2gdo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fusquhe8knewlkp1t2gdo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's what each step (roughly) does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IntelliJ:&lt;/strong&gt; Our IDE. Basically just invokes &lt;code&gt;./gradlew compile&lt;/code&gt; and monitors its output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gradlew:&lt;/strong&gt; The gradle wrapper. A shell script which downloads the desired version of gradle (specified in the build), and passes on whatever arguments you gave it to this specific gradle version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gradle:&lt;/strong&gt; The actual gradle executable. Here, the &lt;code&gt;compileKotlin&lt;/code&gt; call is evaluated, and the task gets passed to the gradle daemon (which is started if it isn't already running).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gradle daemon:&lt;/strong&gt; A background worker created by gradle. Here the actual heavy lifting is performed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;kotlinc:&lt;/strong&gt; The actual kotlin compiler.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two very important things to realize here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gradle, IntelliJ and kotlinc are all implemented on top of the JVM.&lt;/li&gt;
&lt;li&gt;Each of the processes runs in its own JVM instance. From the perspective of the operating system, they are different processes - &lt;strong&gt;with different memory pools&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The conclusion here is that &lt;strong&gt;no matter how much memory you assign to IntelliJ IDEA, it won't change the amount of RAM available to kotlinc upon build&lt;/strong&gt;. Also, no matter how much memory you give to gradle, since kotlinc is its own process, it won't benefit from it.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Fix
&lt;/h1&gt;

&lt;p&gt;With all the insights gathered so far, the question still remains how to assign memory to the kotlinc process. For us, the following worked:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

org.gradle.jvmargs=-Xmx8g -Dkotlin.daemon.jvm.options=-Xmx6g


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We put this line into a file named &lt;code&gt;gradle.properties&lt;/code&gt;, which is located right next to our &lt;code&gt;gradlew&lt;/code&gt; executable (so, top-level in the project). This will assign 8GB of RAM to the gradle process, as well as another 6GB dedicated to the kotlin compiler.&lt;/p&gt;

&lt;p&gt;You can of course play with the numbers. It's an implementation detail of the kotlin gradle plugin whether it calls &lt;code&gt;kotlinc&lt;/code&gt; as a standalone process or embedded, so I took the defensive option and assigned more RAM to gradle than to &lt;code&gt;kotlinc&lt;/code&gt;, but other configurations may work as well.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A note of caution: if you assign more RAM to a JVM via &lt;code&gt;-Xmx&lt;/code&gt; than your OS can actually provide to it, it may fail with a segmentation fault. Never assign more RAM than you actually have.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, if you change those properties in the file and save it, your kotlin compiler may still be slow and/or run out of memory. That's because your gradle daemon may still be running in the background, using your previous settings. Also, IntelliJ has an abundance of caches. The surefire way to make sure your changes are actually taking effect is to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reboot your machine. &lt;em&gt;I mean it&lt;/em&gt;. This will kill the gradle daemon, plus any in-memory caches used by IntelliJ.&lt;/li&gt;
&lt;li&gt;Start IntelliJ.&lt;/li&gt;
&lt;li&gt;Inside IntelliJ, &lt;em&gt;do not click "build"&lt;/em&gt; just yet. Your gradle settings may be served from a persistent cache, which is clearly not what we want. Instead, refresh your gradle project first.&lt;/li&gt;
&lt;li&gt;Once the refresh is completed, perform a full project rebuild from IntelliJ.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  The results
&lt;/h1&gt;

&lt;p&gt;Our builds are now a lot faster again! We went from over 10 minutes at 100% CPU back to less than 1 minute, with much more reasonable CPU loads. Because the change was done in the build setup, our CI/CD server builds are now faster as well.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: This procedure works for Kotlin/JVM for a server-side project built by gradle. It may or may not work for Android builds, Kotlin/JS, Kotlin/Native or multiplatform projects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;If your Kotlin compiles take way longer than they should, and your CPU goes crazy on all cores while kotlin is compiling, consider increasing the maximum heap size of your kotlin compiler. It may be running low on memory.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>gradle</category>
      <category>intellij</category>
      <category>outofmemory</category>
    </item>
    <item>
      <title>Announcing the Chronos Project v1.0.0 Open-Source Release</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Sun, 31 May 2020 11:43:40 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/announcing-the-chronos-project-v1-0-0-open-source-release-1ke6</link>
      <guid>https://dev.to/martinhaeusler/announcing-the-chronos-project-v1-0-0-open-source-release-1ke6</guid>
      <description>&lt;p&gt;Today I'm pleased to announce that Chronos, my long-term data persistence and versioning project for the JDK, has finally been released in its 1.0.0 version as an open-source project &lt;a href="https://github.com/Txture/chronos" rel="noopener noreferrer"&gt;on Github&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Chronos?
&lt;/h1&gt;

&lt;p&gt;The Chronos Project started as my PhD project, but eventually turned into a production-ready versioned database during my work at &lt;a href="//www.txture.io"&gt;Txture&lt;/a&gt;. It offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/Txture/chronos/tree/master/org.chronos.chronodb.api" rel="noopener noreferrer"&gt;ChronoDB&lt;/a&gt;&lt;/strong&gt;: A versioned key-value store&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/Txture/chronos/tree/master/org.chronos.chronograph" rel="noopener noreferrer"&gt;ChronoGraph&lt;/a&gt;&lt;/strong&gt;: A TinkerPop-compliant Graph Database with versioning support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/Txture/chronos/tree/master/org.chronos.chronosphere" rel="noopener noreferrer"&gt;ChronoSphere&lt;/a&gt;:&lt;/strong&gt; An &lt;a href="https://www.eclipse.org/modeling/emf/" rel="noopener noreferrer"&gt;EMF&lt;/a&gt;-compliant model repository&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Versioning
&lt;/h1&gt;

&lt;p&gt;Versioning means that &lt;strong&gt;every change&lt;/strong&gt; made to the database will be &lt;strong&gt;retained and managed&lt;/strong&gt; indefinitely. This allows for the ability of &lt;strong&gt;time travel&lt;/strong&gt; through your data and its history, similar to an &lt;code&gt;AS OF&lt;/code&gt; Query in SQL. Chronos employs a smart data storage layout to ensure that the data is not needlessly duplicated on your hard drive, but you can still access it as if it were.&lt;/p&gt;

&lt;p&gt;Here's a basic example where we fetch yesterday's data with ChronoGraph:&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="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;yesterday&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;currentTimeMills&lt;/span&gt;&lt;span class="o"&gt;()&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;DAYS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toMillis&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="k"&gt;try&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ChronoGraph&lt;/span&gt; &lt;span class="n"&gt;txGraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;createThreadedTx&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yesterday&lt;/span&gt;&lt;span class="o"&gt;)){&lt;/span&gt;
    &lt;span class="c1"&gt;// txGraph will contain the database state as it was yesterday&lt;/span&gt;
    &lt;span class="nc"&gt;Vertex&lt;/span&gt; &lt;span class="n"&gt;johnDoe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;txGraph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;traversal&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;V&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"John Doe"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// johnDoe will also have the same state as it did yesterday&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Branching
&lt;/h1&gt;

&lt;p&gt;In the same way as Chronos offers version control, it also allows for branching in your data, just like you've come to expect it from e.g. Git or SVN:&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="k"&gt;try&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ChronoGraph&lt;/span&gt; &lt;span class="n"&gt;txGraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;createThreadedTx&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-branch"&lt;/span&gt;&lt;span class="o"&gt;)){&lt;/span&gt;
    &lt;span class="c1"&gt;// txGraph now points to branch "my-branch".&lt;/span&gt;
    &lt;span class="c1"&gt;// Everything you do here will only be visible on this branch.&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  ... and much more!
&lt;/h1&gt;

&lt;p&gt;There's a whole bunch of features included in Chronos, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;full ACID transactions&lt;/li&gt;
&lt;li&gt;secondary indexing&lt;/li&gt;
&lt;li&gt;full &amp;amp; incremental backups&lt;/li&gt;
&lt;li&gt;dateback (a &lt;code&gt;rebase&lt;/code&gt;-like API)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All in an open-source project. Free for everyone under the aGPL v3.0 license.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final Words
&lt;/h1&gt;

&lt;p&gt;This project has been very dear to me since its inception, and it will continue to be. I'm proud to release the 1.0.0 version finally as open-source. Visit our &lt;a href="https://github.com/Txture/chronos" rel="noopener noreferrer"&gt;Github Repository&lt;/a&gt; and give it a star if you think it's interesting :)&lt;/p&gt;

</description>
      <category>java</category>
      <category>nosql</category>
      <category>versioning</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Understanding Dependency Injection by writing a DI Container - from scratch! (Part 3)</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Tue, 11 Feb 2020 21:55:43 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/understanding-dependency-injection-by-writing-a-di-container-from-scratch-part-3-1one</link>
      <guid>https://dev.to/martinhaeusler/understanding-dependency-injection-by-writing-a-di-container-from-scratch-part-3-1one</guid>
      <description>&lt;p&gt;This is the third part of my "DI From Scratch" series. In the previous article, we built a basic DI container. Now, we want to take it yet another step further and automatically discover the available service classes.&lt;/p&gt;

&lt;h1&gt;
  
  
  DI Stage 7: Auto-detecting Services
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the source code of this section &lt;a href="https://github.com/MartinHaeusler/blog/tree/master/diFromScratch/src/main/java/org/example/simplecdi/stage7/classpathscan"&gt;on github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our current state represents (a strongly simplified, yet functional) version of libraries such as &lt;a href="https://github.com/google/guice"&gt;Google Guice&lt;/a&gt;. However, if you are familiar with &lt;a href="https://spring.io/projects/spring-boot"&gt;Spring Boot&lt;/a&gt;, it goes one step further. Do you think that it's annoying that we have to specify the service classes explicitly in a set? Wouldn't it be nice if there was a way to auto-detect service classes? Let's find them!&lt;br&gt;
&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;class&lt;/span&gt; &lt;span class="nc"&gt;ClassPathScanner&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// this code is very much simplified; it works, but do not use it in production!&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getAllClassesInPackage&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;packageName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;ClassLoader&lt;/span&gt; &lt;span class="n"&gt;classLoader&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="na"&gt;getContextClassLoader&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;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;packageName&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'.'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'/'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;Enumeration&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;classLoader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResources&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dirs&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;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasMoreElements&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="no"&gt;URL&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextElement&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&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;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFile&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;classes&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;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;findClasses&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;packageName&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="n"&gt;classes&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;findClasses&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;directory&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;packageName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;classes&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;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;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;directory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exists&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="n"&gt;classes&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listFiles&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;files&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;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isDirectory&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;findClasses&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;packageName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"."&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&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;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;endsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".class"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packageName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sc"&gt;'.'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;substring&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="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;6&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="n"&gt;classes&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we have to deal with the &lt;code&gt;ClassLoader&lt;/code&gt; API. This particular API is quite old and dates back to the earliest days of Java, but it still works. We start with a &lt;code&gt;packageName&lt;/code&gt; to scan for. Each &lt;code&gt;Thread&lt;/code&gt; in the JVM has a &lt;code&gt;contextClassLoader&lt;/code&gt; assigned, from which the &lt;code&gt;Class&lt;/code&gt; objects are being loaded. Since the classloader operates on files, we need to convert the package name into a file path (replacing &lt;code&gt;'.'&lt;/code&gt; by &lt;code&gt;'/'&lt;/code&gt;). Then, we ask the classloader for all &lt;em&gt;resources&lt;/em&gt; in this path, and convert them into &lt;code&gt;File&lt;/code&gt;s one by one. In practice, there will be only one resource here: our package, represented as a directory.&lt;/p&gt;

&lt;p&gt;From there, we recursively iterate over the file tree of our directory package, loking for files ending in &lt;code&gt;.class&lt;/code&gt;. We convert every class file we encounter into a class name (cutting off the trailing &lt;code&gt;.class&lt;/code&gt;) to end up with our class name. Then, we finally call &lt;code&gt;Class.forName(...)&lt;/code&gt; on it to retrieve the class.&lt;/p&gt;

&lt;p&gt;So we have a way to retrieve all classes in our base package. How do we use it? Let's add a static factory method to our &lt;code&gt;DIContext&lt;/code&gt; class that produces a &lt;code&gt;DIContext&lt;/code&gt; for a given base package:&lt;br&gt;
&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="nc"&gt;DIContext&lt;/span&gt; &lt;span class="nf"&gt;createContextForPackage&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;rootPackageName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;allClassesInPackage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ClassPathScanner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAllClassesInPackage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rootPackageName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceClasses&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;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;aClass&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;allClassesInPackage&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;   
            &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aClass&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="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DIContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceClasses&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;Finally, we need to make use of this new factory method in our &lt;code&gt;createContext()&lt;/code&gt; method:&lt;br&gt;
&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="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;DIContext&lt;/span&gt; &lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&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;rootPackageName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPackage&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DIContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createContextForPackage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rootPackageName&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;We retrieve the base package name from the &lt;code&gt;Main&lt;/code&gt; class (the class I've used to contain my &lt;code&gt;main()&lt;/code&gt; method). &lt;/p&gt;

&lt;p&gt;But wait! We have a problem. Our classpath scanner will detect &lt;strong&gt;all&lt;/strong&gt; classes, whether they are services or not. We need to tell the algorithm which ones we want with - you guessed it - an annotation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Target&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Retention&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RetentionPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RUNTIME&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;Service&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;Let's annotate our services with it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceAImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&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;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceBImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;... and filter our classes accordingly:&lt;br&gt;
&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="nc"&gt;DIContext&lt;/span&gt; &lt;span class="nf"&gt;createContextForPackage&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;rootPackageName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;allClassesInPackage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ClassPathScanner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAllClassesInPackage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rootPackageName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceClasses&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;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;aClass&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;allClassesInPackage&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;aClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAnnotationPresent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)){&lt;/span&gt;
                &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aClass&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="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DIContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceClasses&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;h1&gt;
  
  
  We are done... are we?
&lt;/h1&gt;

&lt;p&gt;And there you have it - a minimalistic, poorly optimized, yet fully functional DI container. But hold on, why do you need several megabytes worth of library code if the core is so simple? Well...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Our classpath scanner is very wonky. It certainly doesn't cover all cases, nesting depths, inner classes etc. Libraries like &lt;a href="https://github.com/google/guava/wiki/ReflectionExplained#classpath"&gt;Guava's &lt;code&gt;ClassPath&lt;/code&gt;&lt;/a&gt; do a much better job at this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A big advantage of DI is that we can hook into the lifecycle of a service. For example, we might want to do something once the service has been created (&lt;code&gt;@PostConstruct&lt;/code&gt;). We might want to inject dependencies via setters, not fields. We might want to use constructor injection, as we did in the beginning. We might want to wrap our services in proxies to have code executed &lt;em&gt;before&lt;/em&gt; and &lt;em&gt;after&lt;/em&gt; each method (e.g. &lt;code&gt;@Transactional&lt;/code&gt;). All of those "bells and whistles" are provided e.g. by Spring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Our wiring algorithm doesn't respect base classes (and their fields) at all.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Our &lt;code&gt;getServiceInstance(...)&lt;/code&gt; method is very poorly optimized, as it linearly scans for the matching instance every time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will certainly want to have different contexts for testing and production. If you are interested in that, have a look at &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-profiles"&gt;Spring Profiles&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We only have one way of defining services; some might require additional configuration. See Springs &lt;code&gt;@Configuration&lt;/code&gt; and &lt;code&gt;@Bean&lt;/code&gt; annotations for details on that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many other small bits and pieces.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;We have created a very simple DI container which:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;encapsulates the creation of a service network&lt;/li&gt;
&lt;li&gt;creates the services and wires them together&lt;/li&gt;
&lt;li&gt;is capable of scanning the classpath for service classes&lt;/li&gt;
&lt;li&gt;showcases the use of reflection and annotations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also discussed the &lt;strong&gt;reasoning&lt;/strong&gt; for our choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, we replaced static references by objects and constructors.&lt;/li&gt;
&lt;li&gt;Then, we introduced interfaces to further decouple the objects.&lt;/li&gt;
&lt;li&gt;We discovered that cyclic dependencies are a problem, so we introduced setters.&lt;/li&gt;
&lt;li&gt;We observed that calling all setters for building the service network manually is error-prone. We resorted to reflection to automate this process.&lt;/li&gt;
&lt;li&gt;Finally, we added classpath scanning to auto-detect service classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you came this far, thanks for reading along! I hope you enjoyed the read.&lt;/p&gt;

</description>
      <category>java</category>
      <category>dependencyinjection</category>
      <category>spring</category>
      <category>jee</category>
    </item>
    <item>
      <title>Understanding Dependency Injection by writing a DI Container - from scratch! (Part 2)</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Tue, 11 Feb 2020 21:52:40 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/understanding-dependency-injection-by-writing-a-di-container-from-scratch-part-2-2np6</link>
      <guid>https://dev.to/martinhaeusler/understanding-dependency-injection-by-writing-a-di-container-from-scratch-part-2-2np6</guid>
      <description>&lt;p&gt;This is the second part of my "DI From Scratch" series. In the previous article, we discussed our basic example, and the problems there are with the "manual" approach. Now, we want to automate the wiring of our service network.&lt;/p&gt;

&lt;h1&gt;
  
  
  DI Stage 4: Automating the wiring
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the source code of this section &lt;a href="https://github.com/MartinHaeusler/blog/tree/master/diFromScratch/src/main/java/org/example/simplecdi/stage4/collectionofclasses"&gt;on github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's focus on the &lt;code&gt;main()&lt;/code&gt; method, and try to find a more automatic way of creating the service network. Certainly, forgetting to call a setter is a real threat here, and the compiler won't even be able to warn you about it. But our services are structurally different, and there is no &lt;strong&gt;uniform&lt;/strong&gt; way to access them... or is there? Java Reflection to the rescue!&lt;/p&gt;

&lt;p&gt;All we essentially want to provide our setup with is a list of our service classes. From there, the setup should &lt;strong&gt;construct and wire&lt;/strong&gt; the service network. In particular, our &lt;code&gt;main()&lt;/code&gt; method is only really interested in &lt;code&gt;ServiceA&lt;/code&gt;, it doesn't even need &lt;code&gt;ServiceB&lt;/code&gt;. Let's rewrite it like so:&lt;br&gt;
&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceClasses&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;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceAImpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceBImpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="n"&gt;serviceA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createServiceA&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// call business logic&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;out&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="n"&gt;serviceA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jobA&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;But how can we implement the "magic" &lt;code&gt;createServiceA&lt;/code&gt; method? Turns out, it's not &lt;em&gt;that&lt;/em&gt; hard...&lt;br&gt;
&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="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="nf"&gt;createServiceA&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// step 1: create an instance of each service class&lt;/span&gt;
        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceInstances&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;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceClass&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
            &lt;span class="nc"&gt;Constructor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;constructor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConstructor&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAccessible&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="n"&gt;serviceInstances&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newInstance&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// step 2: wire them together&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;serviceInstance&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;serviceInstances&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Field&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;serviceInstance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getDeclaredFields&lt;/span&gt;&lt;span class="o"&gt;()){&lt;/span&gt;
                &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fieldType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;field&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="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAccessible&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="c1"&gt;// find a suitable matching service instance&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;matchPartner&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;serviceInstances&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;fieldType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matchPartner&lt;/span&gt;&lt;span class="o"&gt;)){&lt;/span&gt;
                        &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceInstance&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;matchPartner&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="o"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// step 3: from all our service instances, find ServiceA&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;serviceInstance&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;serviceInstances&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;serviceInstance&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&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="nc"&gt;ServiceA&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceInstance&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;// we didn't find the requested service instance&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;Let's break it down. In &lt;strong&gt;Step 1&lt;/strong&gt; we iterate over our classes, and for each class, we attempt to get the &lt;strong&gt;default constructor&lt;/strong&gt; (i.e. the constructor with no arguments). Since neither &lt;code&gt;ServiceAImpl&lt;/code&gt; nor &lt;code&gt;ServiceBImpl&lt;/code&gt; specifies any constructor (we deleted them when introducing the getters/setters), the Java compiler provides a public default constructor - so that will work fine. Then, we make this constructor &lt;strong&gt;accessible&lt;/strong&gt;. That's just defensive programming to make sure that private constructors will work too. Finally, we call &lt;code&gt;newInstance()&lt;/code&gt; on the constructor to create the instance of the class, and &lt;code&gt;add&lt;/code&gt; it to our set of instances.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Step 2&lt;/strong&gt; we want to wire together our individual service instances. To do so, we look at each service object one by one. We retrieve it's Java class via &lt;code&gt;getClass()&lt;/code&gt;, and ask that class for all of its &lt;code&gt;declaredFields&lt;/code&gt; (&lt;code&gt;declared&lt;/code&gt; means that &lt;code&gt;private&lt;/code&gt; fields will be returned too). Just like for the constructor, we make sure that the field is accessible, and then we check the &lt;code&gt;Type&lt;/code&gt; of the field. This will provide us with the service class we need to put into the field. All that's left to do is to find a suitable &lt;code&gt;matchParter&lt;/code&gt;, an object which is of the type specified by the field. Once we find one, we call &lt;code&gt;field.set(...)&lt;/code&gt; and assign the match partner to the field. Note that the &lt;strong&gt;first parameter&lt;/strong&gt; of the &lt;code&gt;field.set(...)&lt;/code&gt; method is the object which will have its field value changed.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Step 3&lt;/strong&gt;, the network is already complete; all that's left to do is to find the instance of &lt;code&gt;ServiceA&lt;/code&gt;. We can simply scan through or instances and check if we found the right one by using &lt;code&gt;instanceof ServiceA&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This might be a little daunting, so maybe try to read this once more. Also, you might want to brush up on your knowledge of Java reflection basics if any of that seems weird to you.&lt;/p&gt;

&lt;p&gt;So what did we gain?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our services are wired together automatically.&lt;/li&gt;
&lt;li&gt;We can no longer forget to call a setter (in fact, we don't need them anymore).&lt;/li&gt;
&lt;li&gt;Our application will fail &lt;strong&gt;on startup&lt;/strong&gt; if the wiring fails, not during the business logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The primary pain that we need to treat next is the fact that we do not want to repeat this whole procedure every time we want to get a hold of a service; we want to have the ability to access &lt;strong&gt;every&lt;/strong&gt; service in the network, not just one.&lt;/p&gt;

&lt;h1&gt;
  
  
  DI Stage 5: Encapsulating the Context
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the source code of this section &lt;a href="https://github.com/MartinHaeusler/blog/tree/master/diFromScratch/src/main/java/org/example/simplecdi/stage5/context"&gt;on github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The object which is responsible for holding the service network is called the &lt;strong&gt;Dependency Injection Container&lt;/strong&gt;, or (in Spring terms) the &lt;strong&gt;Application Context&lt;/strong&gt;. I'm going to use the "context" terminology, but the terms are really synonyms. The primary job of the context is to provide a &lt;code&gt;getServiceInstance(...)&lt;/code&gt; method which accepts a service class as parameter, and returns the (finished and wired) service instance. So here we go:&lt;br&gt;
&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;class&lt;/span&gt; &lt;span class="nc"&gt;DIContext&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceInstances&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;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;DIContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// create an instance of each service class&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceClass&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
            &lt;span class="nc"&gt;Constructor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;constructor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConstructor&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAccessible&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="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;serviceInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newInstance&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="na"&gt;serviceInstances&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceInstance&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// wire them together&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;serviceInstance&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="na"&gt;serviceInstances&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Field&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;serviceInstance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getDeclaredFields&lt;/span&gt;&lt;span class="o"&gt;()){&lt;/span&gt;
                &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fieldType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;field&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="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAccessible&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="c1"&gt;// find a suitable matching service instance&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;matchPartner&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="na"&gt;serviceInstances&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;fieldType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matchPartner&lt;/span&gt;&lt;span class="o"&gt;)){&lt;/span&gt;
                        &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceInstance&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;matchPartner&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="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@SuppressWarnings&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"unchecked"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&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="no"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;getServiceInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Class&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;serviceClass&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;serviceInstance&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="na"&gt;serviceInstances&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;serviceClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceInstance&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="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceInstance&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;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, the code didn't change much from the previous step, except that we now have an object to encapsulate the context (&lt;code&gt;DIContext&lt;/code&gt;). Internally, it manages a set of &lt;code&gt;serviceInstances&lt;/code&gt; which is created just like before from a collection of service classes. The &lt;strong&gt;Step 3&lt;/strong&gt; from above has moved into its own &lt;code&gt;getServiceInstance&lt;/code&gt; method, which accepts the class to retrieve as a parameter. Since we cannot use &lt;code&gt;instanceof&lt;/code&gt; anymore (it requires a hard-coded class, not a dynamic variable value), we have to fall back to &lt;code&gt;serviceClass.isInstance(...)&lt;/code&gt; to do the same thing.&lt;/p&gt;

&lt;p&gt;We can use this class in our new &lt;code&gt;main()&lt;/code&gt;:&lt;br&gt;
&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;DIContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createContext&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;doBusinessLogic&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;DIContext&lt;/span&gt; &lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceClasses&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;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceAImpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceBImpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DIContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceClasses&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doBusinessLogic&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DIContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="n"&gt;serviceA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getServiceInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getServiceInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;out&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="n"&gt;serviceA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jobA&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;out&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="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jobB&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, we can now easily pull out complete service instances from the context by calling &lt;code&gt;getServiceInstance&lt;/code&gt; as often as we need to, with different input classes. Also note that the services itself can access each other simply by declaring a field of the proper type - they don't even have to know about the &lt;code&gt;DIContext&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;There are still some problems though. For example, what if we want to have a field in our services which does &lt;strong&gt;not&lt;/strong&gt; refer to another service (say, an &lt;code&gt;int&lt;/code&gt; field)? We need a way to &lt;strong&gt;tell our algorithm&lt;/strong&gt; which fields we want it to set - and which ones to leave alone.&lt;/p&gt;

&lt;h1&gt;
  
  
  DI Stage 6: Annotating fields
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the source code of this section &lt;a href="https://github.com/MartinHaeusler/blog/tree/master/diFromScratch/src/main/java/org/example/simplecdi/stage6/annotations"&gt;on github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So how can we tell our algorithm which fields it needs to assign? We could introduce some fancy naming scheme and parse the &lt;code&gt;field.getName()&lt;/code&gt;, but that's a very error prone solution. Instead, we will use an &lt;strong&gt;Annotation&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.annotation.ElementType&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.annotation.Retention&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.annotation.RetentionPolicy&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.annotation.Target&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Target&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FIELD&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Retention&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RetentionPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RUNTIME&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;Inject&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;&lt;code&gt;@Target&lt;/code&gt; tells the compiler on which elements we can use this annotation - we want it to be applicable on fields. With &lt;code&gt;@Retention&lt;/code&gt; we instruct the compiler to keep this annotation until runtime, and not to discard it during compilation.&lt;/p&gt;

&lt;p&gt;Let's annotate our fields:&lt;br&gt;
&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;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceAImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Inject&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// rest is the same as before&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&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;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceBImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Inject&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="n"&gt;serviceA&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// rest is the same as before&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;An annotation in and on itself does &lt;strong&gt;nothing&lt;/strong&gt;. We need to actively &lt;strong&gt;read&lt;/strong&gt; the annotation. So let's do it in the constructor of our &lt;code&gt;DIContext&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;       &lt;span class="c1"&gt;// wire them together&lt;/span&gt;
       &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;serviceInstance&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="na"&gt;serviceInstances&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
           &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Field&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;serviceInstance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getDeclaredFields&lt;/span&gt;&lt;span class="o"&gt;()){&lt;/span&gt;
               &lt;span class="c1"&gt;// check that the field is annotated&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;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAnnotationPresent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Inject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)){&lt;/span&gt;
                   &lt;span class="c1"&gt;// this field is none of our business&lt;/span&gt;
                   &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
               &lt;span class="o"&gt;}&lt;/span&gt;
               &lt;span class="c1"&gt;// rest is the same as before&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run the &lt;code&gt;main()&lt;/code&gt; method again; it should work just like before. However, now you are free to add more fields to your services, and the wiring algorithm won't break.&lt;/p&gt;

&lt;h1&gt;
  
  
  Closing words
&lt;/h1&gt;

&lt;p&gt;So far, we have created a DI container which is very basic but functional. It relies on us providing it with the collection of service classes. In the next part, we will discuss how we can actually &lt;em&gt;discover&lt;/em&gt; our service classes.&lt;/p&gt;

</description>
      <category>java</category>
      <category>dependencyinjection</category>
      <category>spring</category>
      <category>jee</category>
    </item>
    <item>
      <title>Understanding Dependency Injection by writing a DI Container - from scratch! (Part 1)</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Tue, 11 Feb 2020 21:48:15 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/understanding-dependency-injection-by-writing-a-di-container-from-scratch-part-1-1hdf</link>
      <guid>https://dev.to/martinhaeusler/understanding-dependency-injection-by-writing-a-di-container-from-scratch-part-1-1hdf</guid>
      <description>&lt;p&gt;Dependency Injection (DI) can be a very difficult topic to grasp, since there seems to be a lot of "magic" going on. Usually it involves a bunch of annotations scattered all over the place, with objects appearing seemingly out of nowhere. I certainly know that it took me a long while to really understand the concept. If you ever find it hard to understand what Spring and Java EE are doing behind the curtains (and why!), read on!&lt;/p&gt;

&lt;p&gt;In this tutorial, we are going to build a very bare-bones, yet fully functional dependency injection container &lt;strong&gt;from scratch&lt;/strong&gt; in Java. Here are some rules to keep things manageable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Absolutely &lt;strong&gt;no libraries&lt;/strong&gt; allowed, except for the JDK itself.&lt;/li&gt;
&lt;li&gt;No pre-prepared code dumps. We will go through everything and reason about it.&lt;/li&gt;
&lt;li&gt;No bells &amp;amp; whistles, just the basics.&lt;/li&gt;
&lt;li&gt;Performance doesn't matter, no optimizations.&lt;/li&gt;
&lt;li&gt;Executable &lt;code&gt;main()&lt;/code&gt; methods at every step.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In contrast to other articles, I will &lt;strong&gt;not&lt;/strong&gt; explain up-front what DI is or why it is useful. Instead, we'll start with a simple example and let it "evolve".&lt;/p&gt;

&lt;h1&gt;
  
  
  DI Stage 0: Basic example
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the source code of this section &lt;a href="https://github.com/MartinHaeusler/blog/tree/master/diFromScratch/src/main/java/org/example/simplecdi/stage0/staticreferences"&gt;on github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We start with a very basic example. We want two classes, let's call them &lt;code&gt;ServiceA&lt;/code&gt; and &lt;code&gt;ServiceB&lt;/code&gt;, and &lt;code&gt;ServiceA&lt;/code&gt; needs &lt;code&gt;ServiceB&lt;/code&gt; to do its work. Well, you might implement it with &lt;code&gt;static&lt;/code&gt; methods and be done with it! So here goes:&lt;br&gt;
&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;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;jobA&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"jobA("&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jobB&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&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;/code&gt;&lt;/pre&gt;&lt;/div&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;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;jobB&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"jobB()"&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;/code&gt;&lt;/pre&gt;&lt;/div&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;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&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;out&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="nc"&gt;ServiceA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jobA&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If we run this code, it will print:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobA(jobB())
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Cool! So why even bother with more than this? Well...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code is very poor in terms of OO principles. ServiceA and ServiceB should, at the very least, be &lt;em&gt;objects&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The code is tightly coupled and very hard to test in isolation.&lt;/li&gt;
&lt;li&gt;We have absolutely no chance of swapping neither ServiceA nor ServiceB with a different implementation. Imagine one of them is doing credit card billings; you &lt;strong&gt;don't&lt;/strong&gt; want that to actually happen in your test suite.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  DI Stage 1: Getting rid of static references
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the source code of this section &lt;a href="https://github.com/MartinHaeusler/blog/tree/master/diFromScratch/src/main/java/org/example/simplecdi/stage1/constructorinjection"&gt;on github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The main problem we identified in Stage 0 is that there are only static methods, resulting in extremely tight coupling. We would like our services to be objects talking to each other, such that we may replace them as needed. Now the question arises: how does ServiceA know &lt;em&gt;which&lt;/em&gt; ServiceB to talk to? The most basic idea is to simply give our instance of ServiceB to the constructor of ServiceA:&lt;br&gt;
&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;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ServiceA&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&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="na"&gt;serviceB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;jobA&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"jobA("&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="na"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jobB&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Service B didn't change much:&lt;br&gt;
&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;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;jobB&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="s"&gt;"jobB()"&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;... and &lt;code&gt;Main&lt;/code&gt; now needs to assemble the objects before it can call the &lt;code&gt;jobA&lt;/code&gt; method:&lt;br&gt;
&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&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;ServiceB&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="n"&gt;serviceA&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;ServiceA&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceB&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;out&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="n"&gt;serviceA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jobA&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;Nothing fancy here, right? We certainly improved some things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can now replace the implementation of &lt;code&gt;ServiceB&lt;/code&gt; which is used by &lt;code&gt;ServiceA&lt;/code&gt; by providing another object, potentially even of another subclass.&lt;/li&gt;
&lt;li&gt;We can test both services in isolation with a proper test mock for ServiceA.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So all cool? Not quite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's hard to create mocks, as we require a &lt;strong&gt;class&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;It would be much nicer if we required &lt;strong&gt;interfaces&lt;/strong&gt; instead. Also, this would further reduce the coupling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  DI Stage 2: Using interfaces
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the source code of this section &lt;a href="https://github.com/MartinHaeusler/blog/tree/master/diFromScratch/src/main/java/org/example/simplecdi/stage2/constructorwithinterfaces"&gt;on github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So let's use one interface for each of our services. They're about as simple as it gets (I renamed the actual classes to &lt;code&gt;ServiceAImpl&lt;/code&gt; and &lt;code&gt;ServiceBImpl&lt;/code&gt;, respectively):&lt;br&gt;
&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;interface&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;jobA&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;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;interface&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;jobB&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;Now, in &lt;code&gt;ServiceAImpl&lt;/code&gt;, we can actually use the interface:&lt;br&gt;
&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;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceAImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ServiceAImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&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="na"&gt;serviceB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// jobA() is the same as before&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That also makes our &lt;code&gt;main()&lt;/code&gt; method a bit nicer:&lt;br&gt;
&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&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;ServiceBImpl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="n"&gt;serviceA&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;ServiceAImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceB&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;out&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="n"&gt;serviceA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jobA&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;This would be perfectly acceptable for simple use cases from an OO perspective. If you can get away with this, by all means, stop here. However, as your project gets bigger...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it will become more and more complex to &lt;strong&gt;create the network of services&lt;/strong&gt; inside your &lt;code&gt;main()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;you will encounter &lt;strong&gt;cycles&lt;/strong&gt; in your service dependencies which cannot be resolved using constructors as shown in our example.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  DI Stage 3: Breaking the cycle with setters
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the source code of this section &lt;a href="https://github.com/MartinHaeusler/blog/tree/master/diFromScratch/src/main/java/org/example/simplecdi/stage3/setters"&gt;on github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's assume that not only &lt;code&gt;ServiceA&lt;/code&gt; needs &lt;code&gt;ServiceB&lt;/code&gt;, but also the other way around - we have a cycle. Of course, we may still declare a parameter in the constructor of the &lt;code&gt;*Impl&lt;/code&gt; classes, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;
 &lt;span class="c1"&gt;// constructor examples&lt;/span&gt;
 &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ServiceAImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&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="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ServiceBImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="n"&gt;serviceA&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;... but that will do us no good: we will be unable to create an actual &lt;strong&gt;instance&lt;/strong&gt; of either of the two classes. To create an instance of &lt;code&gt;ServiceAImpl&lt;/code&gt;, we would first require an instance of &lt;code&gt;ServiceB&lt;/code&gt;, and to create an instance of &lt;code&gt;ServiceBImpl&lt;/code&gt; we first require an instance of &lt;code&gt;ServiceA&lt;/code&gt;. We're deadlocked.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Side note: there is actually a way out of this by using &lt;strong&gt;proxies&lt;/strong&gt;. However, we're not going to take that route here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So what do we do instead? Well, since we are dealing with cyclic dependencies, we need the ability to first &lt;strong&gt;create&lt;/strong&gt; the services and then &lt;strong&gt;wire&lt;/strong&gt; them together. We do this with setters:&lt;br&gt;
&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;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceAImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// no constructor anymore here!&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- added getter to ServiceA interface&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="nf"&gt;getServiceB&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="n"&gt;serviceB&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="c1"&gt;// &amp;lt;- added setter to ServiceA interface&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setServiceB&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;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;)&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="na"&gt;serviceB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// jobA() same as before&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;main()&lt;/code&gt; method looks like this:&lt;br&gt;
&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// create instances&lt;/span&gt;
        &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&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;ServiceBImpl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="n"&gt;serviceA&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;ServiceAImpl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// wire them together&lt;/span&gt;
        &lt;span class="n"&gt;serviceA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setServiceB&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setServiceA&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceA&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// call business logic&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;out&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="n"&gt;serviceA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jobA&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;Can you see the pattern? First create the objects, then connect them to form the service graph (i.e. service network).&lt;/p&gt;

&lt;p&gt;So why not stop here?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Doing the wiring part manually is error prone. You might forget to call a setter and then it's &lt;code&gt;NullPointerException&lt;/code&gt; galore.&lt;/li&gt;
&lt;li&gt;You might accidentally use a service instance that is still under construction, so it would be beneficial to encapsulate the network construction somehow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Up next
&lt;/h1&gt;

&lt;p&gt;In the next blog post, we will discuss how we can automate the wiring we are doing manually right now.&lt;/p&gt;

</description>
      <category>java</category>
      <category>dependencyinjection</category>
      <category>spring</category>
      <category>jee</category>
    </item>
    <item>
      <title>A Critical Look on Relational Databases and SQL</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Fri, 25 Oct 2019 14:38:59 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/a-critical-look-on-relational-databases-and-sql-158h</link>
      <guid>https://dev.to/martinhaeusler/a-critical-look-on-relational-databases-and-sql-158h</guid>
      <description>&lt;p&gt;Relational Databases took the world by storm around 1990. Ever since, they've become a must-have in the toolbox of professional developers - nearly independent of the language you might be using, you will need SQL at some point. However, since around 2000, the NoSQL movement has regained some attention as well. In this article, I will provide some of my personal thoughts on databases, focusing on relational databases and the SQL language. As I've been working with both relational and non-relational systems, I hope that this article can provide some insights and interesting perspectives.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a strongly opinion-based article based on my personal experience, not a universal truth. Please read it as such.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  The Advantages of Relational Databases
&lt;/h1&gt;

&lt;p&gt;The fact that Relational Database Management Systems (RDBMSs) have such a high market share has several reasons.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relational Algebra
&lt;/h2&gt;

&lt;p&gt;First and foremost, an RDBMS, regardless of its implementation, is always based on &lt;a href="https://en.wikipedia.org/wiki/Relational_algebra"&gt;Relational Algebra&lt;/a&gt; which formally defines its operations and data structures. This is very convenient: all the formal foundations have already been taken care of, the system is known to be sound and complete, "all" database vendors have to do is go ahead and implement them. This is a big difference to NoSQL databases. For example, it is not obvious a priori whether or not you can formulate a query for every possible information demand in a Graph Query language such as &lt;a href="http://tinkerpop.apache.org/docs/current/reference/"&gt;Gremlin&lt;/a&gt; or &lt;a href="https://neo4j.com/developer/cypher-query-language/"&gt;Cipher&lt;/a&gt;. The authors of those languages had to think those theoretical questions through before even writing the first line of code.&lt;/p&gt;

&lt;p&gt;A second reason why RDMBSs are so successful nowadays is the enormous amounts of money which were put into their development. There was a lot of hype surrounding RDBMSs in research, therefore investors were willing to put a lot of money into it. This process spiraled upwards to the point where "database" was used as a synonym to "RDBMS". In a way, RDBMSs became popular not necessarily by means of features or well-foundedness, but at least partially also due to a massive hype cycle which provided the financial resources to make all the research and optimizations happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declarativeness and Optimizations
&lt;/h2&gt;

&lt;p&gt;Another big advantage of RDBMSs is that they can operate in a highly optimized fashion, as SQL is declarative in nature. Operators can be shifted around in the operator tree, indices can be applied where appropriate, there's just a lot of things happening behind the scene before your query even hits the actual B-Trees. Again, there has been a tremendous amount of research efforts going into this topic, and people are still coming up with new ideas on how to make queries even faster. Try using the &lt;code&gt;EXPLAIN&lt;/code&gt; statement in one of your more complex queries to see what I mean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixed Schema for optimal Resource Usage
&lt;/h2&gt;

&lt;p&gt;In most SQL databases out there, the schema has to be fixed up-front. And, aside from special &lt;code&gt;LOB&lt;/code&gt; (&lt;strong&gt;L&lt;/strong&gt;arge &lt;strong&gt;OB&lt;/strong&gt;ject) types such as &lt;code&gt;CLOB&lt;/code&gt; and &lt;code&gt;TEXT&lt;/code&gt;, they pretty much all have a &lt;strong&gt;fixed length&lt;/strong&gt; in bits. Even for a &lt;code&gt;VARCHAR&lt;/code&gt; you have to specify a maximum length. Therefore, for any given row in your database, the system knows in advance how much memory the row will need - &lt;strong&gt;before&lt;/strong&gt; it is actually loaded into RAM. This is a huge deal and helps immensely when implementing database systems in languages with manual memory management, such as C.&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL is a language meant for humans
&lt;/h2&gt;

&lt;p&gt;To many people, in particular in the more business-oriented offices, SQL is much easier to approach than a general-purpose programming language. SQL, as the &lt;a href="https://en.wikipedia.org/wiki/Primus_inter_pares"&gt;primus inter pares&lt;/a&gt; of &lt;a href="https://en.wikipedia.org/wiki/Domain-specific_language"&gt;Domain Specific Languages&lt;/a&gt;, has been designed to be close to natural english. From a marketing perspective, this is a great boon: "Query your data without needing programmers! It's even standardized so you can use any database you want with it!" And I think it's safe to say that it worked, people fell for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Transformation
&lt;/h2&gt;

&lt;p&gt;RDBMSs excel at providing your data exactly in the format you need. They can slice and dice the database content in just about any way you can possibly imagine. This is an impressive and often overlooked capability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Constraints
&lt;/h2&gt;

&lt;p&gt;Relational databases excel at specifying constraints. Whether it is about value constraints (minimum &amp;amp; maximum of a numeric value, null handling...), foreign key constraints or access rights, RDBMSs have you covered in all directions. This ensures that your data remains in a correct and consistent state.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problems and Disadvantages of RDBMSs
&lt;/h1&gt;

&lt;p&gt;As the title implies, I firmly believe that there are a number of issues with RDBMSs out there.&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL is a language for humans
&lt;/h2&gt;

&lt;p&gt;Yes, you read that right - this caption appeared as an advantage. But SQL being a human-readable language also implies a lot of problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It is inherently &lt;strong&gt;non-systematic&lt;/strong&gt;. The number of keywords needed is enormous compared to general-purpose programming languages. In my opinion, this makes it &lt;strong&gt;harder&lt;/strong&gt; to learn, rather than easier, as advertised.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It suffers from &lt;strong&gt;poor composability&lt;/strong&gt;. Unifying two arbitrary queries can be challenging. SQL engines often impose constraints which affect the whole query, rather than individual parts. This becomes particularly evident with &lt;code&gt;GROUP BY&lt;/code&gt; and &lt;code&gt;ORDER BY&lt;/code&gt; clauses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is a &lt;strong&gt;nightmare to parse&lt;/strong&gt;. Read any mailing list on the development of relational databases you want, you will see the people responsible for the parser complain about it, and rightfully so.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In total, the caption of this section could also be written as "SQL is not a language for machines". Let's not forget that the vast majority of queries out there are not written manually - they are being generated. Whether they originate from Object-Relational Mapping systems, string templates or other mechanisms, most queries are not written by a human sitting in front of a text field. SQL as a language therefore focuses on the wrong audience, causing many issues in the process - the generators have a hard time producing it, and the SQL engines have a hard time parsing it. So, who benefits from this situation? Did we, as software development community, take a wrong turn somewhere?&lt;/p&gt;

&lt;h2&gt;
  
  
  The SQL Standard is a bad joke
&lt;/h2&gt;

&lt;p&gt;... and everyone knows it. Even calling it a "Standard" is an insult to real standards. First of all, using only the elements found in the standard, it's already challenging to write a simple &lt;code&gt;SELECT-FROM-WHERE&lt;/code&gt; query. Often times, you &lt;strong&gt;need&lt;/strong&gt; vendor-specific extensions to get your work done (the SQL standard often speaks of "language opportunities"). For instance, you might think that there is a standardized way to do a paginated &lt;code&gt;LIMIT&lt;/code&gt; / &lt;code&gt;OFFSET&lt;/code&gt; query in SQL. Well, too bad, you're out of luck. While pretty much any RDBMS out there &lt;strong&gt;can&lt;/strong&gt; do it, the SQL syntax is &lt;strong&gt;different&lt;/strong&gt; for every one of them. Data types also often don't do the same thing across different vendors. And don't even get me started on stored procedures. There is a reason why companies look for experience with certain RDBMS &lt;strong&gt;products&lt;/strong&gt; in their job announcements, rather than looking for experience with RDBMSs in general. If you see such an advert, you can be sure that this company is already neck deep in the vendor lock-in. In my experience, the idea of writing an application which can make effective use of more than one type of RDBMS as its backend is an illusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;UPSERT&lt;/code&gt;, the unknown being
&lt;/h2&gt;

&lt;p&gt;When dealing with even slightly more sophisticated applications, it is often the case that you load some data from the database, make some modifications to it, and then save it back. RDBMSs have a really bad habit here: they force you as the developer to distinguish between &lt;code&gt;INSERT&lt;/code&gt; and &lt;code&gt;UPDATE&lt;/code&gt;, &lt;strong&gt;all the time&lt;/strong&gt;. Tracking this object state correctly throughout an entire application, only to decide at the final moment which of the two keywords to use, is a real pain. In the end, you put in a lot of effort only to make the SQL constraint checker happy. The &lt;code&gt;UPSERT&lt;/code&gt; keyword has not yet made it into the big RDBMSs. There are ways to do it, in the form of &lt;code&gt;INSERT ON CONFLICT&lt;/code&gt; (PostGreSQL) or &lt;code&gt;ON DUPLICATE KEY UPDATE&lt;/code&gt; (MySQL), but overall the situation is still pretty bad. To add insult to injury, Object-Relational Mappers cannot rely on those features, as they have to talk to multiple different RDBMS backends. In comparison, do you know the primary way of inserting data into Neo4j? It's the &lt;code&gt;MERGE&lt;/code&gt; keyword, which is just another way of saying &lt;code&gt;UPSERT&lt;/code&gt;. Neo4j is not without issues, but they at least got that right from the get-go. There are certainly use cases where it actually makes a difference if you create a new object or update an existing one, but they're a small minority in my experience. In 99% of all cases, I just have an object I want to have saved to query it later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Object-Relational Mappers are a Pain
&lt;/h2&gt;

&lt;p&gt;I don't mean any offense against O/R mapping frameworks or their authors. In fact, I'm thankful they exist, because without them, the pain would be even bigger than it already is. Yes, RDBMSs are powerful and highly optimized, and thousands of hours went into their development to ensure they are correct and fast. We would be mad not to make use of them, right? Well, too bad the interface we have to use to talk to them (SQL) is horrible. I intend to write another article about this topic where I'll go into greater detail.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Future of RDMBSs
&lt;/h1&gt;

&lt;p&gt;RDBMSs are here to stay. Even if all modern applications were developed with NoSQL databases, there would still be enough legacy applications to keep all of us busy for centuries to come. However, change is happening. JSON and XML support is creeping into RDBMS engines, giving us at least some more flexibility. But what about SQL as a language? I personally think that &lt;a href="https://en.wikipedia.org/wiki/Datalog"&gt;Datalog&lt;/a&gt; would be a very nice, clean and effective replacement which is easily generated and easily parsed. I thought of it as a toy when I first came into contact with it in university, but the more time I spend with databases, the more I think that this could very well be worth a shot. Unfortunately, I've never seen any actual support for it in the big database systems.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final thoughts
&lt;/h1&gt;

&lt;p&gt;The relational model has many use cases and advantages, and has come a long way. RDMBSs are stable, mature and have a proven track record. However, SQL as a language is becoming a limiting factor. I think using an RDBMS as the "default" choice for a database is a good habit, but I would advise everyone to at least try a NoSQL solution as well if the opportunity presents itself.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>rdbms</category>
    </item>
    <item>
      <title>Talk &amp; Event Announcement: Kotlin/Everywhere</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Mon, 16 Sep 2019 11:22:22 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/talk-event-announcement-kotlin-everywhere-ifk</link>
      <guid>https://dev.to/martinhaeusler/talk-event-announcement-kotlin-everywhere-ifk</guid>
      <description>&lt;p&gt;Hey all,&lt;/p&gt;

&lt;p&gt;I just wanted to let you know that I will be a speaker at the &lt;strong&gt;&lt;a href="https://www.meetup.com/de-DE/GDG-Innsbruck/events/264345418"&gt;Kotlin/Everywhere&lt;/a&gt;&lt;/strong&gt; event. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What:&lt;/strong&gt;&lt;br&gt;
The event is organized by GDG Innsbruck (Google Developer Group) and hosted by &lt;a href="https://txture.io"&gt;Txture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt;&lt;br&gt;
October 10th 2019, 19:00&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt;&lt;br&gt;
At the Txture headquarters (Grabenweg 68, SOHO 2.0), in the beautiful city of Innsbruck, Austria!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audience:&lt;/strong&gt;&lt;br&gt;
The event is intended for all developers who are interested in the Kotlin language. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speakers:&lt;/strong&gt;&lt;br&gt;
We will have at least two talks, including my own and one by a member of JetBrains, the developers of the Kotlin language!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attendance Fee:&lt;/strong&gt;&lt;br&gt;
None! :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I attend?&lt;/strong&gt;&lt;br&gt;
Just let us know that you'll be attending by subscribing to the event at the &lt;a href="https://www.meetup.com/de-DE/GDG-Innsbruck/events/264345418"&gt;Meetup Page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Talk&lt;/strong&gt;:&lt;br&gt;
I will be talking about our journey with Kotlin at Txture. We use it extensively in production, so we have quite the treasure trove of tales to tell ;)&lt;/p&gt;

&lt;p&gt;Hope to see some of you there!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>java</category>
      <category>spring</category>
      <category>meetup</category>
    </item>
    <item>
      <title>Immutable Data Structures</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Sun, 07 Jul 2019 15:37:41 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/immutable-data-structures-2m70</link>
      <guid>https://dev.to/martinhaeusler/immutable-data-structures-2m70</guid>
      <description>&lt;p&gt;Functional programming is currently on the rise due to its ability to prevent a lot of errors right out of the gate. The two corner stones of the functional paradigm are &lt;strong&gt;pure functions&lt;/strong&gt; and &lt;strong&gt;immutable data structures&lt;/strong&gt;. Today we will look at immutable collections - and why there's more to them than you might think.&lt;/p&gt;

&lt;h1&gt;
  
  
  Levels of Immutability
&lt;/h1&gt;

&lt;p&gt;There are actually several different "levels" of immutability. It's difficult to keep them separated because the terminology is often used in the wrong way. I try to be as clear and consistent as possible.&lt;/p&gt;

&lt;h1&gt;
  
  
  Mutable Collections
&lt;/h1&gt;

&lt;p&gt;Mutable collections are the ones we most commonly see in languages like Java, C# and JavaScript. They are usually built into the standard library. Their primary characteristic is that we can create an instance of those collections, and then afterwards modify it as we please.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&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;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Very high flexibility. There's no use case you cannot cover with mutable collections.&lt;/li&gt;
&lt;li&gt;Fast insertion and modification.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; Very often when you receive a collection as a method argument, you have to make a &lt;strong&gt;defensive copy&lt;/strong&gt;. A full copy is &lt;code&gt;O(n)&lt;/code&gt; in memory and time complexity.&lt;/li&gt;
&lt;li&gt; If you do not create defensive copies, you might end up using a collection and &lt;strong&gt;sharing&lt;/strong&gt; it with another piece of code. If either party makes a change, that change is visible to the other piece of code, potentially breaking it. Such bugs can be extremely subtle and hard to debug.&lt;/li&gt;
&lt;li&gt;Mutable collections do not lend themselves well to concurrent programs. Concurrent modifications on shared mutable collections require &lt;strong&gt;proper external locking&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use them for...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Local variables which are not shared.&lt;/li&gt;
&lt;li&gt;Locally aggregating computation results.&lt;/li&gt;
&lt;li&gt;Fields which get in touch with any reflection-based framework (most prominently, Object-Relational Mappers such as &lt;a href="https://hibernate.org/"&gt;Hibernate&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Collections which are subject to frequent changes by a single thread.&lt;/li&gt;
&lt;li&gt;As a fallback when all other types of collections don't work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Unmodifiable Collections
&lt;/h1&gt;

&lt;p&gt;Unmodifiable collections are merely &lt;strong&gt;views&lt;/strong&gt; on underlying mutable collections. You cannot modify the view, but any modification on the underlying mutable collection will be &lt;strong&gt;visible&lt;/strong&gt; in the view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;original&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;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unmodifiableList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// changing the view is forbidden&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; Runtime exception: the view is unmodifiable!&lt;/span&gt;

&lt;span class="c1"&gt;// reading from the view is fine&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;// changes in the original collection...&lt;/span&gt;
&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Foo"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ... are visible in the view&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Foo"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Useful if you have one object who "owns" the list, and merely lets others read from it.&lt;/li&gt;
&lt;li&gt;If you create an unmodifiable view, and throw away all references to the original, you end up with a truly immutable collection (see below).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The interface of an unmodifiable view is the same as the original collection. Which means: &lt;code&gt;view.add(...)&lt;/code&gt; will be &lt;strong&gt;valid&lt;/strong&gt; according to the compiler. It will appear in your code completion. If you &lt;strong&gt;don't know&lt;/strong&gt; that you are dealing with an unmodifiable view, you're in for a lot of runtime exceptions. Unmodifiable views can fool the user of your API into believing that they are working with mutable collections. Some languages, such as Kotlin, actually &lt;strong&gt;differentiate&lt;/strong&gt; between a &lt;code&gt;List&lt;/code&gt; and a &lt;code&gt;MutableList&lt;/code&gt; interface for this very reason.&lt;/li&gt;
&lt;li&gt;There is no efficient way to create a "changed copy" of an unmodifiable view which contains an additional change. The only way to do that is to &lt;strong&gt;copy&lt;/strong&gt; the entire view content into a new (mutable) collection, and apply the change there. That's &lt;code&gt;O(n)&lt;/code&gt; time and space complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Massive Pitfall:&lt;/strong&gt; If you receive a collection as an argument, and you are calling e.g. &lt;code&gt;Collections.unmodifiableList&lt;/code&gt; on it, you are not safe from external modifications! Remember: you only create a view. The original collection you received may still be changed from the outside. This is therefore &lt;strong&gt;not&lt;/strong&gt; a replacement for defensive copies!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use them for...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sharing your object state with the world in a read-only fashion. Don't forget to document in your API that the collections you return are unmodifiable views.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Persistent Collections
&lt;/h1&gt;

&lt;p&gt;This category of (im)mutability is extremely important, but often overlooked or even mislabeled. Persistent collections have &lt;strong&gt;nothing&lt;/strong&gt; to do with "persistence" as in "storing to disk". Persistent collections are completely &lt;strong&gt;immutable structures&lt;/strong&gt;, except that they offer &lt;strong&gt;smart copy-transforms&lt;/strong&gt;. The primary principle of a persistent data structure is: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you modify the data structure, you get a new data structure which contains the old data, as well as your change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounds familiar? That's exactly what &lt;a href="https://immutable-js.github.io/immutable-js/"&gt;ImmutableJS&lt;/a&gt; does. The name of this library itself is extremely misleading, because what it actually provides are persistent collections, which are much more useful than strictly immutable ones. For Java, there's for example the (aptly named) &lt;a href="https://pcollections.org/"&gt;PCollections&lt;/a&gt; library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;PSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HashTreePSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;empty&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
&lt;span class="nc"&gt;PSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mod1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;plus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;PSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mod2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mod1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;plus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// the original does not know what happened in mod1 and mod2&lt;/span&gt;
&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;
&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;
&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 0&lt;/span&gt;

&lt;span class="c1"&gt;// mod1 knows the original and itself, but does not know about mod2&lt;/span&gt;
&lt;span class="n"&gt;mod1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;mod1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;
&lt;span class="n"&gt;mod1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 1&lt;/span&gt;

&lt;span class="c1"&gt;// mod2 knows original and mod1, as well as its own modification&lt;/span&gt;
&lt;span class="n"&gt;mod2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;mod2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;mod2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The easiest way to think about persistent collections is: make a change, get a &lt;strong&gt;copy&lt;/strong&gt; that includes the change (&lt;strong&gt;copy&lt;/strong&gt; being the operative word). You may think that this is extremely inefficient, as a copy would entail an &lt;code&gt;O(n)&lt;/code&gt; cost in runtime and space complexity. While this naive "copy and change" approach would satisfy the interface, that is acutally &lt;strong&gt;not&lt;/strong&gt; what happens in persistent collections. The trick is that all existing data doesn't change; therefore we are free to reuse it as often as we like. In the example above, &lt;code&gt;mod2&lt;/code&gt; will internally &lt;strong&gt;reuse&lt;/strong&gt; the contents of &lt;code&gt;mod1&lt;/code&gt;. There's no actual copying going on, but you will never realize it, because you cannot &lt;strong&gt;change&lt;/strong&gt; &lt;code&gt;mod1&lt;/code&gt; anymore after creating &lt;code&gt;mod2&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;True, reliable immutability. No need for defensive copies, ever.&lt;/li&gt;
&lt;li&gt;Still relatively easy to work with.&lt;/li&gt;
&lt;li&gt;Safe under concurrent read/write, write/write concurrency can sometimes require additional synchronization.&lt;/li&gt;
&lt;li&gt;All operations on persistent collections are pure functions. No side effects, no surprises.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Nesting of persistent collections can be tricky to pull off (hello, &lt;a href="https://redux.js.org/"&gt;Redux&lt;/a&gt;!).&lt;/li&gt;
&lt;li&gt;If you apply a large amount of modifications to a single persistent data structure, performance will suffer. It might be more efficient to create a mutable copy, apply all your modifications, and then create a persistent version of it (resulting in &lt;code&gt;O(n) + O(n)&lt;/code&gt; space and time complexity).&lt;/li&gt;
&lt;li&gt;If you are unaware that you are working with a persistent collection, you might forget to assign the return value of &lt;code&gt;list.plus("test")&lt;/code&gt; to a variable, and then wonder why &lt;code&gt;"test"&lt;/code&gt; is not in your list.&lt;/li&gt;
&lt;li&gt;Some collection frameworks, such as PCollections, implement the regular (mutable) collection interfaces (e.g. &lt;code&gt;PSet&amp;lt;T&amp;gt;&lt;/code&gt; extends &lt;code&gt;Set&amp;lt;T&amp;gt;&lt;/code&gt;) for compatibility reasons. Thus, the persistent collections inherit the mutating methods, such as &lt;code&gt;void add(E element)&lt;/code&gt; which throw runtime exceptions when called.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use them for...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Representing shared state under read-write access.&lt;/li&gt;
&lt;li&gt;Scenarios with a single producer and multiple concurrent consumers.&lt;/li&gt;
&lt;li&gt;Scenarios where you have to compute multiple alternative solutions which are based on an initial solution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  (Truly) Immutable Collections
&lt;/h1&gt;

&lt;p&gt;Truly immutable collections only offer read access through their API, and have to be filled at creation time. Afterwards, their contents are sealed and set in stone forever. You can think of truly immutable collections as "persistent collections without copy-on-write helpers".&lt;/p&gt;

&lt;p&gt;To the best of my knowledge, there is no truly immutable collection interface in Java. In Kotlin, you can do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// "listOf" creates a truly immutable list in Kotlin.&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true &lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; compile error: interface "List" has no method "add"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy to implement efficiently (all data has to be known in advance)&lt;/li&gt;
&lt;li&gt;Iteration / analysis may be faster than with a persistent collection&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;There is no use case for truly immutable collections which would not work with persistent collections.&lt;/li&gt;
&lt;li&gt;Very limited flexibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use them for...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Defining constants. &lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Closing Thoughts
&lt;/h1&gt;

&lt;p&gt;I hope you enjoyed this tour of (im)mutable collections. It is sometimes hard to properly communicate about this topic because the terminology is often misused. I hope that this blog post will help you in the future to distinguish the types of (im)mutable collection, their pros and cons, and when to use them.&lt;/p&gt;

</description>
      <category>immutability</category>
      <category>collections</category>
      <category>java</category>
      <category>functional</category>
    </item>
    <item>
      <title>Why I stopped using Coroutines in Kotlin</title>
      <dc:creator>Martin Häusler</dc:creator>
      <pubDate>Sat, 22 Jun 2019 11:18:18 +0000</pubDate>
      <link>https://dev.to/martinhaeusler/why-i-stopped-using-coroutines-in-kotlin-kg0</link>
      <guid>https://dev.to/martinhaeusler/why-i-stopped-using-coroutines-in-kotlin-kg0</guid>
      <description>&lt;p&gt;It's not a secret that I'm pretty enthusiastic about Kotlin as a programming language, despite a few &lt;a href="https://dev.to/martinhaeusler/kotlin---the-good-the-bad-and-the-ugly-3jfo"&gt;shortcomings and strange design choices&lt;/a&gt;. I got the chance to work on a medium-sized project using Kotlin, &lt;a href="https://kotlinlang.org/docs/reference/coroutines-overview.html"&gt;Kotlin Coroutines&lt;/a&gt; and the coroutine-driven server framework &lt;a href="https://ktor.io/"&gt;KTOR&lt;/a&gt;. Those technologies offer a lot of merit, however I've found them difficult to work with in comparison to e.g. plain old Spring Boot.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer: I do not intend to "bash" any of those things, my intention is to provide my "user experience" and explain why I will refrain from using them in the future.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Debugging
&lt;/h1&gt;

&lt;p&gt;Consider the following piece of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;retrieveData&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRequest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;remoteCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;postProcess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;remoteCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// do suspending REST call&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us assume we want to debug the &lt;code&gt;retrieveData&lt;/code&gt; function. We place a breakpoint in the first line. Then we start the debugger (in IntelliJ in my case), it stops at the breakpoint. Nice. Now we perform a &lt;code&gt;Step Over&lt;/code&gt; (skipping the call &lt;code&gt;createRequest&lt;/code&gt;). That works too. However, if we &lt;code&gt;Step Over&lt;/code&gt; again, the program will just &lt;em&gt;run&lt;/em&gt;. It will &lt;strong&gt;NOT&lt;/strong&gt; stop after &lt;code&gt;remoteCall&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why is that? The JVM debugger is attached to a &lt;code&gt;Thread&lt;/code&gt; object. For all means and purposes, this is a very reasonable choice. However, when Coroutines enter the mix, one thread no longer does one thing. Look closely: &lt;code&gt;remoteCall(request)&lt;/code&gt; calls a &lt;code&gt;suspend&lt;/code&gt;ing function - we don't see it in the syntax when we call it though. So what happens? We tell the debugger to "step over" the method call. The debugger runs the code for the remote call and waits.&lt;/p&gt;

&lt;p&gt;This is where things get difficult: the current thread (to which our debugger is bound) is only an executor for our coroutine. What will happen when we call a &lt;code&gt;suspending&lt;/code&gt; function is that at some point, the suspending function will &lt;code&gt;yield&lt;/code&gt;. This means that &lt;strong&gt;a different &lt;code&gt;Thread&lt;/code&gt; will continue the execution of our method&lt;/strong&gt;. We effectively tricked the debugger.&lt;/p&gt;

&lt;p&gt;The only workaround I've found is to place a breakpoint on the line I want to go to, rather than using &lt;code&gt;Step Over&lt;/code&gt;. Needless to say, this is a major pain. And apparently &lt;a href="https://youtrack.jetbrains.com/issue/KT-27573"&gt;it's not just me&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Furthermore, in general debugging it is very hard to pin down what a single coroutine is currently doing, as it jumps between threads. Sure, coroutines are named and you can enable the logging to print not only the thread but the coroutine name as well, but the mental effort required to debug coroutine-based code is a lot higher in my experience than thread-based code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Binding data to the REST call
&lt;/h1&gt;

&lt;p&gt;When working on a microservice, a common pattern is to receive a REST call with some form of authentication, and pass the same authentication along for all internal calls to other microservices. In the most trivial case, we at least want to keep the username of the caller.&lt;/p&gt;

&lt;p&gt;However, what if those calls to other microservices are nested 10 levels deep in our call stacks? Surely we don't want to pass along an &lt;code&gt;authentication&lt;/code&gt; object as a parameter in each and every function. We require some form of "context" which is implicitly present.&lt;/p&gt;

&lt;p&gt;In traditional thread-based frameworks such as Spring, the solution to this problem is to use a &lt;code&gt;ThreadLocal&lt;/code&gt; object. This allows us to bind any kind of data to the current thread. As long as one thread corresponds to the processing of one REST call (which you should always aim for), this is exactly what we need. A good example for this pattern is Spring's &lt;a href="https://github.com/spring-projects/spring-security/blob/master/core/src/main/java/org/springframework/security/core/context/ThreadLocalSecurityContextHolderStrategy.java"&gt;&lt;code&gt;SecurityContextHolder&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With coroutines, the situation is different. A &lt;code&gt;ThreadLocal&lt;/code&gt; will no longer do the trick, because your workload will jump from one thread to another; it is no longer the case that one thread will accompany a request during the entirety of its lifetime. In kotlin coroutines, there's the &lt;a href="https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html"&gt;&lt;code&gt;CoroutineContext&lt;/code&gt;&lt;/a&gt;. In essence, it is nothing more than a &lt;code&gt;HashMap&lt;/code&gt; which is carried alongside the coroutine (no matter on which thread it mounts). It has a horribly over-engineered API and is cumbersome to use, but that is not the main issue here.&lt;/p&gt;

&lt;p&gt;The real problem is that &lt;strong&gt;coroutines do not inherit the context automatically&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;jobs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Deferred&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// we lose our context here!&lt;/span&gt;
            &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;awaitAll&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever you call a coroutine builder, such as &lt;code&gt;async&lt;/code&gt;, &lt;code&gt;runBlocking&lt;/code&gt; or &lt;code&gt;launch&lt;/code&gt;, you will - by default - lose your current coroutine context. You can avoid it by passing the context into the builder method explicitly, but &lt;em&gt;god forbid&lt;/em&gt; you ever forget to do that (the compiler won't care!).&lt;/p&gt;

&lt;p&gt;A child coroutine could start off with an empty context, and if a request for a context element comes in and nothing is found, the parent coroutine context could be asked for the element. However, that does not happen in Kotlin, the programmer is required to do that manually, every single time.&lt;/p&gt;

&lt;p&gt;If you are interested in the details of this issue, I recommend having a look at &lt;a href="https://blog.tpersson.io/2018/04/22/emulating-request-scoped-objects-with-kotlin-coroutines/"&gt;this blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;code&gt;synchronized&lt;/code&gt; will no longer do what you think it does
&lt;/h1&gt;

&lt;p&gt;When working with locks or &lt;code&gt;synchronized&lt;/code&gt; blocks in Java, the semantic I am thinking about is usually along the lines of "nobody else can enter while I'm in  this block". The &lt;em&gt;nobody else&lt;/em&gt; part of course implies that there is an "identity" of some sort, which in this case is the &lt;code&gt;Thread&lt;/code&gt;. That should raise a big red warning sign in your head by now.&lt;/p&gt;

&lt;p&gt;Let's consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;lock&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ReentrantLock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;doWithLock&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
   &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withLock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nf"&gt;callSuspendingFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;em&gt;dangerous&lt;/em&gt;. Even if &lt;code&gt;callSuspendingFunction()&lt;/code&gt; does nothing harmful, the code will not behave as you might think it does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter the lock&lt;/li&gt;
&lt;li&gt;Call the suspending function&lt;/li&gt;
&lt;li&gt;The coroutine yields, the current thread still holds the lock&lt;/li&gt;
&lt;li&gt;Another thread picks up our coroutine&lt;/li&gt;
&lt;li&gt;We are the same coroutine, but we do not own the lock anymore!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The number of potentially conflicting, deadlocking or otherwise unsafe scenarios is staggering. You might argue that we "just" need to engineer our code to handle that. I would agree, however we are talking about the JVM. There is a vast ecosystem of libraries out there. And &lt;em&gt;they&lt;/em&gt; are not prepared to handle it.&lt;/p&gt;

&lt;p&gt;The upshot here is: &lt;strong&gt;the moment you start using coroutines, you forfeit the possibility to use a lot of Java libraries, simply because they expect a thread-based environment.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Throughput vs. Horizontal Scaling
&lt;/h1&gt;

&lt;p&gt;A big advantage of coroutines for the server-side is that a single thread can handle a lot more requests; while one request waits for a database response, the same thread can happily serve another request. In particular for I/O bound tasks, this can increase the throughput.&lt;/p&gt;

&lt;p&gt;However, as this blog post has hopefully demonstrated to you, there &lt;em&gt;is&lt;/em&gt; a non-zero cost associated with using coroutines, on many levels.&lt;/p&gt;

&lt;p&gt;The question which arises is: is the benefit worth that cost? And in my opinion the answer is &lt;strong&gt;no&lt;/strong&gt;. In cloud- and microservice-environments, there should always be some scaling mechanism, whether it is Google AppEngine, AWS Beanstalk, or some form of Kubernetes. Those technologies will simply spawn new instances of your microservice on demand if the current load increases. Therefore, the throughput one individual instance can handle is much less important, considering all the hoops we would have to jump through for using coroutines. This reduces the value we get from using coroutines.&lt;/p&gt;

&lt;h1&gt;
  
  
  Coroutines have their place
&lt;/h1&gt;

&lt;p&gt;Coroutines are still useful. When developing client-side UIs where there is only one UI thread, coroutines can help to improve your code structure while being compliant with the requirements of your UI framework. I've heard that this works pretty well on Android. Coroutines are an interesting topic, however for the server-side I feel that we are not quite there yet. The JVM developers are currently working on &lt;a href="https://www.youtube.com/watch?v=vbGbXUjlRyQ"&gt;Fibers&lt;/a&gt;, which are in essence also coroutines, but they have the goal to play nicely with the JVM infrastructure. It will be interesting to see how this effort develops, and how Jetbrains will react to it with respect to their own coroutine solution. In the best possible scenario, Kotlin coroutines will just "map" to Fibers in the future, and debuggers will be smart enough to handle them properly.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>jvm</category>
      <category>server</category>
    </item>
  </channel>
</rss>
