<?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: Marko Milenkovic</title>
    <description>The latest articles on DEV Community by Marko Milenkovic (@mare_milenkovic).</description>
    <link>https://dev.to/mare_milenkovic</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%2F608892%2F2ec8aa50-a1b3-4160-9920-f3561bd8a116.jpg</url>
      <title>DEV Community: Marko Milenkovic</title>
      <link>https://dev.to/mare_milenkovic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mare_milenkovic"/>
    <language>en</language>
    <item>
      <title>Best Practices That You Should Follow When Extracting Zip Archive in Java</title>
      <dc:creator>Marko Milenkovic</dc:creator>
      <pubDate>Mon, 17 Apr 2023 18:17:10 +0000</pubDate>
      <link>https://dev.to/mare_milenkovic/best-practices-that-you-should-follow-when-extracting-zip-archive-in-java-oom</link>
      <guid>https://dev.to/mare_milenkovic/best-practices-that-you-should-follow-when-extracting-zip-archive-in-java-oom</guid>
      <description>&lt;p&gt;Extracting archive files without controlling resource consumption is security-sensitive and can lead to denial of service.&lt;/p&gt;

&lt;p&gt;Our code executes on servers, but you should know that servers have limits. Based on this, check how many hardware resources your code can consume. Resources are CPU, RAM, disk, network... Understand those limits and, based on those limits, put thresholds in your code.&lt;/p&gt;

&lt;p&gt;Here are some important thresholds you should put in a code when extracting a zip archive.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Limit the size of an extracted archive
&lt;/h3&gt;

&lt;p&gt;This is the most basic and critical threshold you should introduce when extracting a zip archive.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to limit extracted size?
&lt;/h4&gt;

&lt;p&gt;You can check the size after you extract the archive, but this can be too late. If the extracted content is too big, it can drain your server resources.&lt;/p&gt;

&lt;p&gt;You should include a size threshold check in the extraction process. Each time you extract and get some bytes from an archive, compare the total extracted size with the threshold.&lt;/p&gt;

&lt;p&gt;Zip archives also have metadata. In metadata, you can find each entry's file size. But, as another application wrote metadata, this information doesn't need to be correct.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Limit the number of entries in an archive
&lt;/h3&gt;

&lt;p&gt;Each file system has some limitations in terms of the number of files and directories that can handle in a directory/partition/hard drive... Those limits are usually huge numbers. Even so, this is a limited resource. In the &lt;a href="https://rules.sonarsource.com/java/type/Security%20Hotspot/RSPEC-5042" rel="noopener noreferrer"&gt;Sonar article&lt;/a&gt; there is the following statement:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Too many entries in an archive, can lead to inodes exhaustion of the system.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Inodes are indexes that point to the actual location of a file on a disk. If you have too many small files on the file system, it can drain out available inodes. Consequently, your system cannot store new files.&lt;/p&gt;

&lt;p&gt;Inodes are used on the linux/unix file systems, but a similar limit also exists for windows. Source: &lt;a href="https://stackoverflow.com/a/7163783" rel="noopener noreferrer"&gt;stackoverflow&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Protect yourself against zip bomb
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Successful Zip Bomb attacks occur when an application expands untrusted archive files without controlling the size of the expanded data, which can lead to denial of service.&lt;/code&gt; Source: &lt;a href="https://rules.sonarsource.com/java/type/Security%20Hotspot/RSPEC-5042" rel="noopener noreferrer"&gt;Sonar article&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Zip bomb is usually a malicious archive file of a few kilobytes with extracted content measured in gigabytes. To achieve this extreme compression ratio, attackers will compress irrelevant data (e.g., a long string of repeated bytes).&lt;/p&gt;

&lt;p&gt;You can have a total archive file size threshold, but you should always strive to fail fast. The compression ratio can give you an idea of whether the data in the archive is relevant. The data compression ratio for most legit archives is 1 to 3. And in the example from the sonar article threshold is 10, which should be a good value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.bamsoftware.com/hacks/zipbomb/" rel="noopener noreferrer"&gt;Here&lt;/a&gt; you can find example zip bomb files.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Sanitize zip files
&lt;/h3&gt;

&lt;p&gt;Sure, here is the revised version in Markdown format with grammatical corrections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Run a virus scan on a zip file before performing any other action.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can help prevent malicious files from being uploaded and potentially causing harm to the server or other users.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Check the content of the zip archive.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The content of a zip archive is stored sequentially as a sequence of bytes,&lt;br&gt;
   followed by a central directory at the end of the file.&lt;br&gt;
   The central directory contains metadata about all zip content.&lt;br&gt;
   For each file, it contains a relative path inside the zip archive.&lt;br&gt;
   This can create a problem as it can allow a ZipSlip attack&lt;br&gt;
   because a user can enter the file name in the form &lt;code&gt;..\..\file&lt;/code&gt;,&lt;br&gt;
   leading to the extraction of a zip file in an unwanted location.&lt;/p&gt;

&lt;p&gt;To fix this, add the following check:&lt;br&gt;
   the canonical path of the file does not start with the path of the target directory.&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="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="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;extractDirPath&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zipEntry&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;if&lt;/span&gt;&lt;span class="o"&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;getCanonicalPath&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extractDirPath&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SecurityException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ZipEntry not within target directory!"&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;ul&gt;
&lt;li&gt;&lt;strong&gt;Check file extensions inside the zip file.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They should match the file extensions that are allowed by your application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Change the filename to something generated by the application.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use UUID to generate the file name.&lt;br&gt;
   This can help prevent conflicts between files and make it harder for an attacker to predict filenames,&lt;br&gt;
   which can be useful in certain types of attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Don't extract archives inside an archive
&lt;/h3&gt;

&lt;p&gt;This will also create the same problem as with extracting folder content. It is better to go with one of the following options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Treat archive files in the archive as all other files - don't extract them.&lt;/li&gt;
&lt;li&gt;Check with the business if you can forbid the archive files inside an archive. You can ask this question because compressing an already compressed archive will not lead to a smaller file. \
You can forbid archive entries by checking entry extension and mime type during the extraction process.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  6. Don't rely only on archive entry metadata
&lt;/h3&gt;

&lt;p&gt;Archives contain metadata that you can read during the extraction process. Compressing application wrote this data in an archive during the compression process.&lt;/p&gt;

&lt;p&gt;The problem with this is that if you rely only on those properties, you need to trust a compressing application that is not in your control. Hackers can create fake metadata and crush your application.&lt;/p&gt;

&lt;p&gt;Be careful when using zip archive metadata. Always ask yourself how attackers can abuse it to hack your extraction algorithm.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sources:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/ZIP_%28file_format%29" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sonarsource.com/blog/the-hidden-flaws-of-archives-in-java/" rel="noopener noreferrer"&gt;The Risk of Archive Extraction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP - File Upload Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>zip</category>
    </item>
    <item>
      <title>Meetings Best Practices</title>
      <dc:creator>Marko Milenkovic</dc:creator>
      <pubDate>Wed, 14 Dec 2022 18:31:59 +0000</pubDate>
      <link>https://dev.to/mare_milenkovic/meetings-best-practices-53gg</link>
      <guid>https://dev.to/mare_milenkovic/meetings-best-practices-53gg</guid>
      <description>&lt;p&gt;In the previous period, I had a lot of meetings, so I came up with a list of best meeting practices that can help you be better at meetings:&lt;/p&gt;

&lt;h3&gt;
  
  
  Before a meeting:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Check if you can resolve the issue you have without organizing a meeting. Create a chat group, or email, try to understand the problem better, and try to solve the issue by yourself.
There are several reasons for this.

&lt;ol&gt;
&lt;li&gt;The more people you need, the harder it is to find a time that is suitable for everybody.&lt;/li&gt;
&lt;li&gt;Meetings are expensive for the company.&lt;/li&gt;
&lt;li&gt;People are usually busy with their work.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;If the subject is urgent, ignore the first point.&lt;/li&gt;

&lt;li&gt;Prepare the meeting agenda.&lt;/li&gt;

&lt;li&gt;Check all participants' calendars and choose the best time for a meeting.&lt;/li&gt;

&lt;li&gt;Schedule a meeting and send the meeting agenda.&lt;/li&gt;

&lt;li&gt;Prepare yourself for the meeting - do your homework/research.
You can do this by scheduling another meeting for yourself (book the time).&lt;/li&gt;

&lt;li&gt;Everybody needs to prepare for the meeting (even if you're not the meeting organizer).&lt;/li&gt;

&lt;/ol&gt;

&lt;h3&gt;
  
  
  During the meeting:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Don't be distracted by something else (chat messages, phone, other tickets...). Follow the meeting and be active. (This is very hard sometimes :D)&lt;/li&gt;
&lt;li&gt;If you think that the subject is not relevant to you, then you should check with a meeting organizer why you're called to the meeting. (Mistakes can happen)&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  After the meeting:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;The meeting organizer needs to send meeting follow-up notes with actions defined in the meeting.&lt;/li&gt;
&lt;li&gt;The meeting organizer can ask for feedback from some or all the participants.&lt;/li&gt;
&lt;li&gt;If you think a meeting was not productive, inform the organizer and give him proposals for improvement.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm sure that this list is not complete. If you have good meeting practices, please share them with me.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If you are needed for some part of the meeting, you can ask the group to leave the meeting after the discussion on your subject is over.&lt;/li&gt;
&lt;li&gt;The good idea is to write your meeting notes (even if you're not an organizer).&lt;/li&gt;
&lt;li&gt;At the end of the meeting, you should have a defined list of actions.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>career</category>
      <category>softwaredevelopment</category>
      <category>learning</category>
    </item>
    <item>
      <title>Setting up Junit 5 Parallel Test Execution With Maven</title>
      <dc:creator>Marko Milenkovic</dc:creator>
      <pubDate>Thu, 03 Nov 2022 06:40:14 +0000</pubDate>
      <link>https://dev.to/mare_milenkovic/setting-up-junit-5-parallel-test-execution-with-maven-4cnc</link>
      <guid>https://dev.to/mare_milenkovic/setting-up-junit-5-parallel-test-execution-with-maven-4cnc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;We need fast-build pipelines. This is because we need fast feedback from our pipeline in order to be more productive. If something is wrong with our code, then we want our pipeline to fail fast. To accomplish that, you may decide to allow parallel test execution for tests in your project. This post describes how to do that with Maven and Junit 5.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started With Junit 5 and Maven
&lt;/h2&gt;

&lt;p&gt;To get started with Junit 5, you need to import the following dependency into the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.junit.jupiter&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter-engine&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;5.9.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the time of writing this article, version &lt;em&gt;5.9.0&lt;/em&gt; is the newest. You should check &lt;a href="https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine" rel="noopener noreferrer"&gt;maven repository&lt;/a&gt; for a new version. Notice, that we imported the library in &lt;em&gt;test&lt;/em&gt; scope as there is no need for this library to be in production code because we only use it for running tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Tests in Parallel
&lt;/h2&gt;

&lt;p&gt;Maven offers you two ways for running tests in parallel:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;By starting multiple JVM instances&lt;/li&gt;
&lt;li&gt;By using multiple threads in the same JVM instance&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. By Using the Parallel Parameter
&lt;/h3&gt;

&lt;p&gt;The setup for parallel test execution is straightforward. Include the following parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;forkCount&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/forkCount&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It must have a value greater than 1 to enable parallel execution. It is important to know that parallel execution is achieved by starting multiple JVM child processes. This has multiple consequences, and it can affect your decision to use this method. Maven starts multiple JVM instances, and this means that it consumes more memory. Each thread has its own memory space. But it accomplishes a greater level of test independence, as processes cannot share data. You can use this method when you need to use an in-memory database for your unit tests.&lt;/p&gt;

&lt;p&gt;The parameter &lt;code&gt;forkCount&lt;/code&gt; has a fixed positive integer value which represents the number of forks. Of course, it is usual that multiple developers work on the same project, and we don't know how many cores other developers will have on their machines. To better use hardware, it would be great if we can set this parameter to create a number of forks that depends on the number of cores on CPU. Maven supports this, and you can configure it in the following way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;forkCount&amp;gt;&lt;/span&gt;1C&lt;span class="nt"&gt;&amp;lt;/forkCount&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration instructs Maven to create one fork for each core. If your CPU has two virtual threads per core, you can also enter &lt;code&gt;2C&lt;/code&gt;to use most CPU resources. Or if you don't want to use &lt;code&gt;100%&lt;/code&gt; of your CPU, you can enter &lt;code&gt;0.5C&lt;/code&gt; which will instruct Maven to create forks for the half of CPU cores. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. By Setting up Junit Multi-Thread Execution
&lt;/h3&gt;

&lt;p&gt;Maven uses plugins for everything. This is also the case for running project tests. To run project tests, Maven uses the Surefire plugin. Unfortunately, it uses the old version of the plugin by default, which doesn't support Junit5 test execution. So, we need to import a newer version of this plugin to Maven. To include a newer version of this plugin, we need to configure Maven. We can do this by adding the following XML to the &lt;code&gt;pom.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;pluginManagement&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-surefire-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.0.0-M7&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    We will add configuration here
                &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/pluginManagement&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;XML&lt;/code&gt; is quite self-descriptive. We add new plugin that is in &lt;code&gt;build-&amp;gt;pluginManagement-&amp;gt;plugins&lt;/code&gt; section of Maven &lt;code&gt;pom.xml&lt;/code&gt;. We import the newest version of the surefire plugin at the time of writing this article. You can check &lt;a href="https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-surefire-plugin/3.0.0-M7" rel="noopener noreferrer"&gt;this url&lt;/a&gt; for a newer version.&lt;/p&gt;

&lt;p&gt;Now, when we have a newer version of the surefire plugin loaded, we can continue to configure Maven for multithreaded test execution. &lt;/p&gt;

&lt;p&gt;In the official Maven documentation, to achieve this, you need to use &lt;code&gt;parallel, threadCount&lt;/code&gt; and &lt;code&gt;useUnlimitedThreads&lt;/code&gt; parameters. I tried all these parameters, but nothing worked with Junit 5. By checking official documentation for Maven Surefire and Junit 5 we can conclude that Junit 5 supports a new multithreaded execution model (which is still in the preview phase). So, to configure multithreaded execution, we need to configure Junit5 as well. We can do this by setting up properties in the Maven configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;configurationParameters&amp;gt;&lt;/span&gt;
            junit.jupiter.execution.parallel.enabled=true
            ...
        &lt;span class="nt"&gt;&amp;lt;/configurationParameters&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another option is to create &lt;code&gt;junit-platform.properties&lt;/code&gt; file. Put it into &lt;code&gt;test/resources&lt;/code&gt; folder, and put all the properties in that file instead of &lt;code&gt;pom.xml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is enough to set &lt;code&gt;junit.jupiter.execution.parallel.enabled=true&lt;/code&gt; to allow parallel test execution. But, if you try running the test after setting up this parameter value to &lt;code&gt;true&lt;/code&gt; it will surprise you to see that tests are still running sequentially. The reason for this is that there are 2 strategies in which you can allow parallel execution in tests.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Junit can assume that all tests are sequential, and only ones that are annotated with &lt;code&gt;@Execution(CONCURRENT)&lt;/code&gt; will be executed in parallel. You can use this annotation on a class or test method to enable parallel execution.&lt;/li&gt;
&lt;li&gt;You can set parameter &lt;code&gt;junit.jupiter.execution.parallel.mode.default = concurrent&lt;/code&gt;. Here, all tests will run in parallel by default except ones annotated with &lt;code&gt;ExecutionMode.SAME_THREAD&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How Many Threads Junit Will Use for Parallel Execution?
&lt;/h3&gt;

&lt;p&gt;This is also configurable property &lt;code&gt;junit.jupiter.execution.parallel.config.strategy=dynamic&lt;/code&gt; and it also has default value &lt;code&gt;dynamic&lt;/code&gt;. Strategy can also be &lt;code&gt;fixed&lt;/code&gt; or &lt;code&gt;custom&lt;/code&gt;. If we set up &lt;code&gt;fixed&lt;/code&gt; value for this property, then we also need to set up the value for the &lt;code&gt;junit.jupiter.execution.parallel.config.fixed.parallelism=&amp;lt;positive integer&amp;gt;&lt;/code&gt;. This is not a scalable solution, and we should use &lt;code&gt;dynamic&lt;/code&gt; value to better utilize the hardware.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dynamic&lt;/code&gt; property also has a connected property that influences how many threads JUnit will create. &lt;code&gt;junit.jupiter.execution.parallel.config.dynamic.factor=&amp;lt;positive decimal number&amp;gt;&lt;/code&gt;. Factor to multiply by the number of processors/cores to determine the desired parallelism for the dynamic configuration strategy.&lt;/p&gt;

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

&lt;p&gt;Parallel test execution can speed up your build, but you must be careful when enabling it, as it will not always provide you with better performance. This is because the tests may use the same resource, and they can wait for each other to access it. Because of that, it is always a good idea to test and check everything.&lt;/p&gt;

&lt;p&gt;Another more significant problem with parallel tests is if the tests are not independent, there can be &lt;a href="https://www.techtarget.com/whatis/definition/flaky-test" rel="noopener noreferrer"&gt;flaky tests&lt;/a&gt;. They are very hard to debug and identify.&lt;/p&gt;

&lt;p&gt;If you liked this post, you can follow me on &lt;a href="https://twitter.com/mare_milenkovic" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/marko-milenkovic-48320b59/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; for more content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html" rel="noopener noreferrer"&gt;Maven documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://junit.org/junit5/docs/snapshot/user-guide/#writing-tests-parallel-execution" rel="noopener noreferrer"&gt;Junit guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://antkorwin.com/junit5/junit5_parallel_execution.html" rel="noopener noreferrer"&gt;JUnit5 Parallel Execution of tests&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>testdev</category>
      <category>junit</category>
      <category>optimization</category>
    </item>
    <item>
      <title>I Asked a Java Champion: What Is the Biggest Problem That Professional Java Developers Are Facing Today?</title>
      <dc:creator>Marko Milenkovic</dc:creator>
      <pubDate>Tue, 26 Oct 2021 15:00:41 +0000</pubDate>
      <link>https://dev.to/mare_milenkovic/i-asked-a-java-champion-what-is-the-biggest-problem-that-professional-java-developers-are-facing-today-3joa</link>
      <guid>https://dev.to/mare_milenkovic/i-asked-a-java-champion-what-is-the-biggest-problem-that-professional-java-developers-are-facing-today-3joa</guid>
      <description>&lt;p&gt;I have attended the workshop that is organized by the &lt;a href="https://itkonekt.com/en/" rel="noopener noreferrer"&gt;ITKonekt&lt;/a&gt;. The workshop was about efficient coding practices for best performance in Java. Java Champion &lt;a href="https://victorrentea.ro/" rel="noopener noreferrer"&gt;Victor Rentea&lt;/a&gt; did a great job explaining all java internals, tools, hibernate, threads, collections, garbage collections, and much more. It was very enjoyable to learn from him and I decided to ask him the question: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the biggest problem that professional Java developers are facing today?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;His initial answer was: "Not writing enough Java. They write Kubernetes scripts, dev-ops scripts, python scripts…" &lt;/p&gt;

&lt;p&gt;My understanding of this is that those people are very experienced developers. He also mentioned that this is what his colleagues are working on currently. But if you are just starting your career, he has advice for you: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are starting a career, then you should learn the language and frameworks that you are using. You should master the language and frameworks. This is the first challenge.&lt;/li&gt;
&lt;li&gt;Don't be disgusted by the front-end technologies, try to be full stack after you master Java. This is after you are comfortable with Java. Go a bit full stack, not "full full" stack, but "just a bit" full stack. &lt;/li&gt;
&lt;li&gt;Try to learn more about what surrounds you. Learn some other language. Kotlin is a good one. * Learn dev ops. Try to learn a bit of everything. He also gave me this advice: As long as you are surrounded by people smarter than you, you are good. And as long as you love to work with your team, you are good. Doesn’t matter project or technology, it can be a terrible legacy system. If you have super cool surroundings and you keep learning and you keep having fun, it’s perfect. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you liked this post, you can follow me on &lt;a href="https://twitter.com/mare_milenkovic" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/marko-milenkovic-48320b59/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Victor is a great trainer and one of the best presenters. You can find him at the following links: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Web site &lt;a href="http://victorrentea.ro/" rel="noopener noreferrer"&gt;victorrentea.ro&lt;/a&gt; you can find a &lt;strong&gt;blog&lt;/strong&gt;, some &lt;strong&gt;recorded talks&lt;/strong&gt;, plus other &lt;strong&gt;goodies&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.meetup.com/bucharest-software-craftsmanship-community/" rel="noopener noreferrer"&gt;Bucharest-software-craftsmanship-community&lt;/a&gt; (3000+ developers). &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/victorrentea" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="http://www.linkedin.com/in/victor-rentea-trainer" rel="noopener noreferrer"&gt;LinkedIN&lt;/a&gt;, &lt;a href="https://fb.me/VictorRentea.ro" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtube.com/vrentea" rel="noopener noreferrer"&gt;Victor’s YouTube Channel&lt;/a&gt; there is more recorded and live content, including coding katas, past meetups, and more.&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>10 mistakes that java developers make that prevent them from being successful developers</title>
      <dc:creator>Marko Milenkovic</dc:creator>
      <pubDate>Fri, 11 Jun 2021 09:54:23 +0000</pubDate>
      <link>https://dev.to/mare_milenkovic/10-mistakes-that-java-developers-make-that-prevent-them-from-being-successful-developers-2fj6</link>
      <guid>https://dev.to/mare_milenkovic/10-mistakes-that-java-developers-make-that-prevent-them-from-being-successful-developers-2fj6</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZGOgS8iT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://theprofdev.files.wordpress.com/2021/06/10-mistakes.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZGOgS8iT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://theprofdev.files.wordpress.com/2021/06/10-mistakes.png%3Fw%3D1024" alt="10 mistakes" width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on my previous experience, I created a list of 10 mistakes that developers made, preventing them from being a great developer. Here is the list:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Not writing unit tests
&lt;/h2&gt;

&lt;p&gt;Developers that don’t write unit tests produce more bugs from the code they write and maintain. That leads to unstable products and client dissatisfaction.&lt;br&gt;&lt;br&gt;
If you are not familiar with writing unit tests, there are some resources to get started with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.vogella.com/tutorials/Mockito/article.html" rel="noopener noreferrer"&gt;https://www.vogella.com/tutorials/Mockito/article.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.baeldung.com/mockito-series" rel="noopener noreferrer"&gt;https://www.baeldung.com/mockito-series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.softwaretestinghelp.com/mockito-tutorial/" rel="noopener noreferrer"&gt;https://www.softwaretestinghelp.com/mockito-tutorial/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  2. Not manually testing code
&lt;/h2&gt;

&lt;p&gt;Even if you completely cover your code with unit tests, there is still a chance that you missed something out. It happens in practice that some error pushes through.&lt;br&gt;&lt;br&gt;
It is always good practice to manually test code before pushing it for code review. By doing this, you will look at your solution from the client’s perspective. And not only that you can detect bugs, but you can also identify design problems in the development stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Having the mindset “This will never happen”
&lt;/h2&gt;

&lt;p&gt;Developers often make mistakes when they write new code by thinking that certain scenarios in code will never happen. Eventually, it turns out that they are wrong. In those situations, applications can behave unpredictably and it can lead to bugs. Handle every scenario that code can go into.&lt;br&gt;&lt;br&gt;
Defensive programming techniques will help you in that. If you are not familiar with defensive programming, you can check the following Pluralsight course: &lt;a href="https://www.pluralsight.com/courses/defensive-programming-java" rel="noopener noreferrer"&gt;https://www.pluralsight.com/courses/defensive-programming-java&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Not asking for feedback and not giving feedback
&lt;/h2&gt;

&lt;p&gt;To improve yourself, regularly ask for feedback. You can as for feedback when you finish a ticket, or after finishing a project, or when you do a presentation… There is no bad time to ask for feedback.&lt;br&gt;&lt;br&gt;
Give feedback to your colleagues. And not by telling them they are great even if you think they are not so good. Tell them areas where they can improve themselves. If the feedback is honest, they will appreciate you more.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Not checking the performance of code
&lt;/h2&gt;

&lt;p&gt;Often, developers write their code, but they don’t check for performance. When code goes to production, it creates various problems. Poor performance can even crush the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Writing long procedural code
&lt;/h2&gt;

&lt;p&gt;It is very easy to write long methods with a bunch of logic. By doing this, programmers put the same logic in many places.&lt;br&gt;
Projects with a lot of small methods have much greater code reusability and are much easier to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Not being familiar with the tools
&lt;/h2&gt;

&lt;p&gt;Tools are extensions of your hands. The better you know them, the more productive you will be. You should be very familiar with the IDE you use.&lt;br&gt;&lt;br&gt;
Learn shortcuts, they will make you much more productive. Try learning one shortcut to a day and create your personal cheat sheet.&lt;br&gt;&lt;br&gt;
Research plugins, usually you will find a plugin that will help you be even more productive. Plugins that will help you write better code in Intellij Idea are Sonar Lint, Spot bugs, and Code Metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Ignoring problems in code
&lt;/h2&gt;

&lt;p&gt;Developers that are working on the most successful products are changing the code all the time. Don’t be afraid to refactor code. If your code is unit tested, then there is a low probability of introducing a regression.&lt;br&gt;&lt;br&gt;
But, don’t stop there. Developers often ignore problematic code that is not part of their ticket. As a developer, you are responsible to maintain an application and keep it in good shape. Because of that, fix all problems that you find.&lt;br&gt;&lt;br&gt;
The best way to proceed with fixing the problem is to create a ticket and work on it with your team. The following story emphasizes why it is important not to ignore problems in code: &lt;a href="https://blog.codinghorror.com/the-broken-window-theory/" rel="noopener noreferrer"&gt;https://blog.codinghorror.com/the-broken-window-theory/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Coding by accident
&lt;/h2&gt;

&lt;p&gt;Developers should NEVER do a code modification and push that code in production without understanding the consequences of it. Code can produce correct results for given test values. However, there can be scenarios where it can produce unpredicted results and create serious problems.&lt;br&gt;&lt;br&gt;
Coding by accident often happens when developers use features from libraries that don’t completely understand. It can also happen when the developer solves the problem without understanding the solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Not asking for help
&lt;/h2&gt;

&lt;p&gt;Developers are not very communicative people. They like to solve problems by themselves. The era where one developer creates a complete solution from start to end is over.&lt;br&gt;&lt;br&gt;
Developing software is a team activity. When you encounter a problem during programming, try to solve it by yourself. But don’t waste too much time if you can’t figure out the solution. There is a high probability that some of your colleagues already encounter the same problem and know a solution.&lt;br&gt;&lt;br&gt;
If it is not the case, then you will get help and the team will understand that the problem is complex and that you need time to solve it. Involving more people will help you resolve complex problems faster. Developers that don’t ask for help, usually spend too much time on a ticket.&lt;br&gt;&lt;br&gt;
Help others when you see they have problems with their ticket. As a result, the team will be more productive and people will like you more.&lt;/p&gt;

&lt;p&gt;If you like this content, you can follow me on &lt;a href="https://twitter.com/mare_milenkovic" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/marko-milenkovic-48320b59/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>developers</category>
      <category>development</category>
      <category>java</category>
    </item>
    <item>
      <title>How do I become proficient with functional programming in Java</title>
      <dc:creator>Marko Milenkovic</dc:creator>
      <pubDate>Mon, 05 Apr 2021 13:50:19 +0000</pubDate>
      <link>https://dev.to/mare_milenkovic/how-do-i-become-proficient-with-functional-programming-in-java-52pa</link>
      <guid>https://dev.to/mare_milenkovic/how-do-i-become-proficient-with-functional-programming-in-java-52pa</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgzmn4ha3ks4ov0f17or.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgzmn4ha3ks4ov0f17or.png" alt="FP in Jav" width="800" height="486"&gt;&lt;/a&gt; &lt;br&gt;
As a Java developer, I always look for ways to improve my coding skills. I heard about functional programming (FP) back when I was a student. Then, FP was not very popular and most developers considered code written using FP to be slow. &lt;/p&gt;

&lt;p&gt;Time has changed and today FP is very popular. Some developers are considering it to be the future of how developers write code.&lt;/p&gt;

&lt;p&gt;FP is the most useful concept that I learned in the last several years. It helped me to become a better developer. I started writing cleaner code with fewer bugs. &lt;/p&gt;

&lt;h3&gt;
  
  
  Here are the immediate benefits I got from FP:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I sharpen my skills related to using Java Streams. It is much easier for me to work with Streams when I understand FP concepts. &lt;/li&gt;
&lt;li&gt;My functions that follow FP concepts are easy to understand and maintain. There is no risk to using them in a concurrent environment. The reusability of those functions is much greater. &lt;/li&gt;
&lt;li&gt;If you are not a fan of “if” and “for” statements, then you will like FP. It can help you write more understandable code that doesn’t include those statements. I can do more with fewer lines of code.&lt;/li&gt;
&lt;li&gt;The FP is a declarative paradigm. With FP you describe what you want, rather than how to get it. This means that the code is more readable, reusable, and it is easier to maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  So, how I started with functional programming?
&lt;/h3&gt;

&lt;p&gt;We can find a ton of material on the internet related to FP. I usually like to watch video material when I want to learn about a new subject.&lt;/p&gt;

&lt;p&gt;I attended an online presentation hold by Venkat Subramaniam. It was a great and inspiring presentation. The good news is that you can watch it on the following link: &lt;a href="https://www.youtube.com/watch?v=15X0qFtBqiQ&amp;amp;t=135s" rel="noopener noreferrer"&gt;Functional Programming with Java 8&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After that presentation, I gained an interest in FP, so I decided to study more about FP. I watched the Pluralsight course &lt;a href="https://www.pluralsight.com/courses/functional-programming-big-picture" rel="noopener noreferrer"&gt;Functional Programming: The Big Picture&lt;/a&gt;. This course helped me understand the big picture of FP and why it matters.&lt;/p&gt;

&lt;p&gt;The next natural step was to check if there is a course that's subject is related to implementing FP concepts in Java. I found the course &lt;a href="https://www.pluralsight.com/courses/applying-functional-programming-techniques-java" rel="noopener noreferrer"&gt;Applying Functional Programming Techniques in Java&lt;/a&gt;. It is a great course. It helped me learn, understand, and apply new FP concepts in Java.&lt;/p&gt;

&lt;p&gt;After watching those courses, I wanted to know more about Monads. They are very important in FP. Following two videos helped me understand Monads: &lt;a href="https://www.youtube.com/watch?v=ZhuHCtR3xq8&amp;amp;t=14s" rel="noopener noreferrer"&gt;Brian Beckman: Don't fear the Monad&lt;/a&gt; and &lt;a href="https://youtu.be/OSuu8zBBNAA" rel="noopener noreferrer"&gt;What the ƒ is a Monad?&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Learn from Haskell
&lt;/h4&gt;

&lt;p&gt;I started learning Haskell. At the end of Venkat Subramaniam's presentation, I asked him if learning Haskell will help me better understand FP concepts. The answer was something like: “Not only Haskell helped me to understand FP, Haskell LEARNED ME how to write good code”. Some developers say that learning Haskell is like learning programming again from scratch. I learned great stuff from Haskell, and it was easy and fun to get started with it. &lt;a href="http://learnyouahaskell.com/chapters" rel="noopener noreferrer"&gt;Learn You a Haskell for Great Good!&lt;/a&gt; is a great tutorial to get started with Haskell.&lt;/p&gt;

&lt;h4&gt;
  
  
  Learn some FP language
&lt;/h4&gt;

&lt;p&gt;If you don’t like Haskell, don’t worry, you can learn another FP language. You can check Kotlin, Scala, F#, Clojure, Elixir, Erlang... &lt;/p&gt;

&lt;p&gt;If you want to stick with JVM, then you can learn Kotlin, Scala, or Clojure. Kotlin and Scala support functional and OOP paradigms and Java developers can easily get started with them. Kotlin is a new language, Spring framework supports it, and some Java developers started switching to it. Because of those reasons, I suggest trying Kotlin.&lt;/p&gt;

&lt;p&gt;Clojure is a modern Lisp variant that runs on JVM. It is useful to know that Lisp is the oldest FP language. Also, Uncle Bob is using Clojure.&lt;/p&gt;

&lt;h3&gt;
  
  
  My experience with Functional Programming
&lt;/h3&gt;

&lt;p&gt;To get familiar with FP, I studied and applied in practice FP concepts. The most important concepts that I learned are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Immutability&lt;/strong&gt; - I have as many as possible immutable objects in my codebase. This leads to fewer places where I can change the state of the program. And that leads to fewer bugs. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Referential transparency&lt;/strong&gt; - I write as much as possible pure functions. Those functions are like mathematical functions. For the same input, they always have the same output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pure and unpure functions&lt;/strong&gt; - before FP, I was not aware of this concept. Now, I separate pure functions from unpure. It allowed me to easier test the code and improved my code reusability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Function Composition&lt;/strong&gt; - promotes better code readability and it is easier to write code by composing functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Curried Functions&lt;/strong&gt; - brilliant concept, but it is not natural to use it in Java like in other FP languages. I don’t use them for now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lazy evaluation&lt;/strong&gt; - evaluate values when they are needed. Lambdas are the way to do a lazy evaluation in Java.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher-Order functions&lt;/strong&gt; - receive other functions as parameters in existing functions. Those functions are usually utility functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Map, filter, reduce pattern&lt;/strong&gt; - Java Stream API implements this pattern. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monads&lt;/strong&gt; - helped me understand how to handle unpure functions safely. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional class&lt;/strong&gt; - FP provides an efficient solution on how to work with nullable objects. I always return the Optional object instead of null in a method that can return null.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Railway programming&lt;/strong&gt; - helped me understand how Stream API and Optional class works.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using FP in code doesn’t prevent us, developers, from writing bad code. We still need to write unit tests, have a good understanding of our task and our codebase. We still need to apply all the best practices that we learned in the past. FP is promoting good practices and makes it easier for us developers to write good and maintainable code. &lt;/p&gt;

&lt;p&gt;I plan to further learn about FP and Java. I will continue to write posts on this subject. For updates, you can follow me on &lt;a href="https://twitter.com/mare_milenkovic" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/marko-milenkovic-48320b59/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>functional</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
