<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Vladimir D on Medium]]></title>
        <description><![CDATA[Stories by Vladimir D on Medium]]></description>
        <link>https://medium.com/@Vladimir_D?source=rss-8ba234925f31------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*qUyrzfpituh3N6p-6SzMlQ.jpeg</url>
            <title>Stories by Vladimir D on Medium</title>
            <link>https://medium.com/@Vladimir_D?source=rss-8ba234925f31------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 06 Jun 2026 13:01:24 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@Vladimir_D/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[What’s new in JUnit 6: Key Changes and Improvements]]></title>
            <link>https://medium.com/javarevisited/whats-new-in-junit-6-key-changes-and-improvements-551a84d7ed1f?source=rss-8ba234925f31------2</link>
            <guid isPermaLink="false">https://medium.com/p/551a84d7ed1f</guid>
            <category><![CDATA[software-testing]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[automation-testing]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Vladimir D]]></dc:creator>
            <pubDate>Wed, 01 Oct 2025 14:36:31 GMT</pubDate>
            <atom:updated>2025-10-01T14:36:31.865Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*CCCBEo06t57M76mjvhEUXA.png" /></figure><p>JUnit 6 is here, eight years after JUnit 5 was released. This isn’t just an incremental update; it’s a significant modernization leap.</p><p>Let’s explore the main breaking changes and improvements.</p><h3>JUnit 6 requires Java 17+ (and Kotlin 2.2+)</h3><p>JUnit 6 raises the minimum required Java version from 8 to 17. This change is driven by two key factors:</p><ol><li>Java’s evolution: a lot of improvements have been introduced since version 8.</li><li>Ecosystem shift towards Java 17.</li></ol><p>For example:</p><ul><li>Spring Framework 6 and Spring Boot 3 <a href="https://spring.io/blog/2022/03/28/an-update-on-java-17-adoption">has changed its baseline to Java 17+</a>.</li><li>AssertJ <a href="https://github.com/assertj/assertj/issues/3442">has moved to Java 17+</a>.</li></ul><blockquote>For projects still using Java versions older than 17, JUnit 5 will continue to be supported for at least one more year.</blockquote><p>For Kotlin users, JUnit 6 now requires Kotlin 2.2 or later.</p><h3>JUnit Platform, Jupiter, and Vintage share the same version</h3><p>The JUnit framework consists of three major architecture components:</p><ul><li>Platform — provides the engine API for launching tests.</li><li>Jupiter — provides the API for writing tests.</li><li>Vintage — implements an engine that allows running tests written in JUnit 3 and 4.</li></ul><p>However, in JUnit 5 only Jupiter and Vintage artifacts shared the same version, while the Platform artifacts followed a separate versioning scheme.</p><p>For example:</p><ul><li>junit-jupiter-engine:5.13.3</li><li>junit-vintage-engine:5.13.3</li><li>junit-platform-engine:<strong>1.13.3</strong></li></ul><p>As you can see, the junit-platform-engine version differs from others.</p><p>To simplify the dependency management, <em>JUnit 6 unifies versioning across all the components</em>, meaning that all three of them, including JUnit Platform, will share the same version.</p><p>As a result, after migrating to JUnit 6, a single version can be used:</p><ul><li>junit-jupiter-engine:6.0.0</li><li>junit-vintage-engine:6.0.0</li><li>junit-platform-engine:<strong>6.0.0</strong></li></ul><h3>Various improvements and deprecated APIs</h3><p>JUnit 6 introduces significant cleanup of the codebase by removing deprecated APIs and behaviors, while also adding several improvements:</p><p>New features and API improvements:</p><ul><li>Kotlin’s suspend modifier may now be applied to test and lifecycle methods.</li><li>Display names for @ParameterizedClass and @ParameterizedTest now consistently style name-value pairs for arguments using name = value formatting – for example, fruit = apple instead of fruit=apple.</li><li>For consistency with test methods, @Nested classes declared in the same enclosing class or interface are now ordered in a deterministic but intentionally nonobvious way.</li></ul><p>Public API deprecations and removals:</p><ul><li>The JRE enum constants for JAVA_8 to JAVA_16 have been deprecated because they can no longer be used at runtime since JAVA_17 is the new baseline.</li><li>@EnabledForJreRange and @DisabledForJreRange now use JAVA_17 as their default min value.</li><li>MethodOrderer.Alphanumeric class removed.</li><li>ReflectionSupport.loadClass(String) method removed.</li><li>ReflectionUtils.readFieldValue(…​) method removed.</li><li>ReflectionUtils.getMethod(…​) method</li><li>InvocationInterceptor.interceptDynamicTest(Invocation, ExtensionContext) method removed.</li><li>The JUnit Vintage engine is now deprecated and will report an INFO level discovery issue when it finds at least one JUnit 4 test class.</li></ul><p>Module removals and integrations:</p><ul><li>junit-platform-runner and junit-platform-jfr modules removed. The JFR functionality is now integrated in junit-platform-launcher.</li><li>The junit-platform-suite-commons module is now integrated into junit-platform-suite.</li><li>The junit-jupiter-migrationsupport artifact and its contained classes are now deprecated and will be removed in the next major version.</li></ul><p>Build tools compatibility:</p><ul><li>Support for Maven Surefire/Failsafe versions less than 3.0.0 has been dropped.</li></ul><blockquote>The full list of changes can be found in the official <a href="https://docs.junit.org/snapshot/release-notes/index.html#release-notes-6.0.0">Release Notes</a>.</blockquote><h3>More consistent and performant CSV parsing for @CsvSource and @CsvFileSource</h3><p>JUnit 6 <a href="https://github.com/junit-team/junit-framework/issues/4339">has migrated its CSV parsing</a> implementation from the no longer maintained <a href="https://github.com/uniVocity/univocity-parsers">univocity-parsers</a> library to <a href="https://fastcsv.org/">FastCSV</a>.</p><p>This provides:</p><ul><li>More consistent CSV input handling (including for malformed entries).</li><li>Better error reporting.</li><li><a href="https://github.com/junit-team/junit-framework/issues/4339#issuecomment-2994362440">Improved performance</a>.</li></ul><p>Although the overall behavior remains largely compatible with JUnit 5, there are a few notable changes that <em>might require updates to your tests or input files:</em></p><ul><li>The lineSeparator attribute in @CsvFileSource has been removed. The line separator is now automatically detected, meaning that any of \r, \n, or \r\n is treated as a line separator.</li><li>Extra characters after a closing quote are no longer allowed in @CsvSource and @CsvFileSource. For example, if a single quote is used as the quote character, the following CSV value &#39;foo’INVALID,&#39;bar&#39; will now cause an exception to be thrown. This helps ensure that malformed input is not silently accepted or misinterpreted.</li><li>Attributes such as ignoreLeadingAndTrailingWhitespace, nullValues, and others in @CsvSource and @CsvFileSource now apply to header fields as well as to regular fields.</li><li>Root causes and messages of exceptions thrown for malformed CSV input may differ in some cases.</li></ul><blockquote>If your test suite includes complex or custom-formatted CSV data, it’s worth reviewing and validating it after migration.</blockquote><h3>JUnit 6 enhances null-safety with <a href="https://jspecify.dev/">JSpecify</a> annotations</h3><p>In JUnit 5, nullability was described informally via JavaDoc — useful for human readers, but invisible to tools. This led to a few common issues:</p><ul><li>NullPointerExceptions at runtime.</li><li>Extra casting or null-safety assertions in Kotlin, due to its distinction between nullable and non-nullable types</li></ul><p>JUnit 6 addresses these issues by introducing <a href="https://jspecify.dev/">JSpecify</a> annotation support. These annotations are:</p><ul><li>Recognized by IDEs.</li><li>Supported by static analysis tools like <a href="https://medium.com/r?url=https%3A%2F%2Ferrorprone.info%2F">ErrorProne</a> and <a href="https://medium.com/r?url=https%3A%2F%2Fgithub.com%2Fuber%2FNullAway%3Ftab%3Dreadme-ov-file">NullAway</a>.</li><li><a href="https://jspecify.dev/docs/whether/#kotlin">Processed by the Kotlin compiler</a>.</li></ul><p>Starting with JUnit 6, all public APIs consistently declare their nullability using the @Nullable annotation.</p><p>For example, the Arguments.of() method now clearly indicates it accepts null arguments while always returning a non-null value:</p><pre>static Arguments of(@Nullable Object... arguments) {<br>  return of(arguments);<br>}</pre><blockquote>Non-annotated types are considered non-nullable by default.</blockquote><h3>Conclusion</h3><p>JUnit 6 represents a major evolution of the testing framework. While not a complete rewrite like JUnit 5 was, it delivers substantial improvements by:</p><ul><li>Embracing modern Java language features.</li><li>Introducing comprehensive null-safety through <a href="https://jspecify.dev/">JSpecify</a>.</li><li>Simplifying dependency management.</li></ul><h3><strong>Useful links:</strong></h3><ul><li><a href="https://docs.junit.org/snapshot/release-notes/index.html#release-notes-6.0.0">JUnit 6 Release Notes</a></li><li><a href="https://nipafx.dev/junit-5-architecture-jupiter/">JUnit architecture overview</a> by <a href="https://medium.com/u/62d4a2cf0eec">Nicolai Parlog</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=551a84d7ed1f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/javarevisited/whats-new-in-junit-6-key-changes-and-improvements-551a84d7ed1f">What’s new in JUnit 6: Key Changes and Improvements</a> was originally published in <a href="https://medium.com/javarevisited">Javarevisited</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Oracle Java Certification: do you need it?]]></title>
            <link>https://medium.com/javarevisited/oracle-java-certification-is-it-worth-it-f8d1fa000409?source=rss-8ba234925f31------2</link>
            <guid isPermaLink="false">https://medium.com/p/f8d1fa000409</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[oracle]]></category>
            <dc:creator><![CDATA[Vladimir D]]></dc:creator>
            <pubDate>Mon, 30 Sep 2024 08:21:04 GMT</pubDate>
            <atom:updated>2024-10-06T16:57:20.038Z</atom:updated>
            <content:encoded><![CDATA[<p>OCP Java SE certification is infamous for its difficulty and a wide variety of topics. It requires a lot of time and determination to pass the exam, but the real question is: <em>Is it worth investing your money and effort to earn the title of “Oracle Certified Professional Java SE Developer”</em>?</p><p>I’ve spent about 400$ and six everyday-study months to get it and I want to help you decide whether this exam is worth your time and effort.</p><p>A quick note, I passed Java SE <strong>17 </strong>exam but given that all currently available OCP exams have similar structure and require about the same amount of study, my advice will probably be applicable to other versions as well.</p><p>Let’s start with what you’ll basically need to pass an exam and then see what benefits you get from it.</p><h3>Price</h3><p>The first and most obvious is that you need to buy an attempt to take an exam. The attempt is <strong>single-use</strong> meaning that you have only one try and if you fail — you’ll need to buy another one attempt.</p><p>The price ranges from 240$ to 300$ depending on your location. It isn’t cheap, that’s why I recommend you to talk to your management and let them sponsor this certification for you.</p><p>That was exactly my case, it was set as a part of my Personal Development Plan and my company agreed to pay for it.</p><p>Actually, it’s a common case, many companies encourage their engineers to pass industry recognised certifications, it’s especially true for outsourcing companies whose reputation benefits from having certified developers on board or companies relying heavily on Java ecosystem.</p><p>You’ll also need solid preparation resources to pass the exam from the first attempt. I recommend<a href="https://www.amazon.com/Oracle-Certified-Professional-Developer-Certification/dp/111986464X"> <strong>OCP Oracle Certified Professional Java SE 17 Developer Certification Kit</strong></a> by Jeanne Boyarsky and Scott Selikoff (≈75$) and<a href="https://enthuware.com/"> <strong>Enthuware mock exams</strong></a> (≈10$).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ebMPNYoeC7C38MoAcPLY-Q.png" /></figure><h3><strong>Difficulty and preparation</strong></h3><p>The exam is fairly difficult even if you already have a couple of years of professional experience.</p><p>It covers a broad range of topics and some of them are not very common nowadays: <em>Serialization</em>, <em>JDBC (PreparedStatement, CallableStatement, ResultSet</em> etc.), <em>Java Platform Module System</em>.</p><p>You’ll need to grasp not just the basics of these technologies, but also be prepared to solve tricky questions — especially if you haven’t worked with them in real-world scenarios.</p><p>Fortunately, most questions focus on more familiar topics like <em>Java Object-Oriented Approach</em>, <em>Stream API</em>, <em>Arrays and Collections.</em> Making sure you know the basics is important but as always be ready for tricky questions.</p><p>Also, each exam covers features added since the previous LTS version, for example <em>OCP Java 17</em> covers <em>Record Classes (introduced in Java 14)</em> and <em>Sealed Classes and Interfaces (Java 15). </em>Thus it may require an additional effort to learn new language features.</p><p>Last but not least: the exam includes questions about <em>Concurrency</em> and <em>I/O</em>. Both topics are quite challenging so I highly recommend spending extra time brushing up on them.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0ntDDSopmxmMZQtpCqSqKw.jpeg" /><figcaption><a href="https://www.amazon.com/Oracle-Certified-Professional-Developer-Certification/dp/111986464X">The Study Guide (theory &amp; tests)</a> I used to prepare for the exam</figcaption></figure><h3>Is it worth it?</h3><p>The exam <strong>will be beneficial if</strong> you want to:</p><ul><li>have an official confirmation of your knowledge and stand out during a recruitment process;</li><li>deeper explore core language APIs, cover gaps and become familiar with newest language features;</li><li>be able to read code faster and become a better code-reviewer;</li><li>get a confidence boost after achieving a challenging goal.</li></ul><p>However, the exam <strong>may not be for you</strong> if you:</p><ul><li>have just started learning Java;</li><li>are not ready to invest 3–9 months in continuous learning;</li><li>already possess solid confirmation of your skills;</li><li>don’t wish to spend some time learning topics in which you’re not particularly interested in.</li></ul><p>The road to OCP Certification is a challenging but rewarding journey and I wish you success if you decide to take it!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dPbnzOzWwrsmLCcZaY4ctw.jpeg" /></figure><h4>Useful links</h4><ul><li><a href="https://education.oracle.com/java-se-17-developer/pexam_1Z0-829">Exam topics</a></li><li><a href="https://coderanch.com/c/certification">Success stories from people passed the exam, Q&amp;A</a></li><li><a href="https://education.oracle.com/buy-exam">Buy an exam attempt</a></li><li><a href="https://www.udemy.com/course/1z0-819-certification-oracle-java-17-exam-practice-test/?couponCode=GET_JAVA_CERTIFIED">Java 17 Practice Test</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f8d1fa000409" width="1" height="1" alt=""><hr><p><a href="https://medium.com/javarevisited/oracle-java-certification-is-it-worth-it-f8d1fa000409">Oracle Java Certification: do you need it?</a> was originally published in <a href="https://medium.com/javarevisited">Javarevisited</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Lazy vs Eager Singleton in Java]]></title>
            <link>https://medium.com/javarevisited/lazy-singleton-in-java-part-1-is-there-a-difference-af4aaaeb071f?source=rss-8ba234925f31------2</link>
            <guid isPermaLink="false">https://medium.com/p/af4aaaeb071f</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[software-patterns]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Vladimir D]]></dc:creator>
            <pubDate>Sun, 09 Jul 2023 17:17:00 GMT</pubDate>
            <atom:updated>2024-10-05T15:45:37.940Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/752/0*oUTFqJAcXuQTEfmk" /><figcaption><a href="https://www.wallpaperflare.com/cat-kittens-animals-nature-baby-animals-mirror-reflection-wallpaper-bdcv">https://www.wallpaperflare.com/cat-kittens-animals-nature-baby-animals-mirror-reflection-wallpaper-bdcv</a></figcaption></figure><h3>Introduction</h3><p>We’ve all seen Singletons lots of times. In most cases, the implementation of this pattern looks rather formulaic and doesn’t raise any questions. But recently, in various projects, I started coming across a “Lazy” implementation, which puzzled me. My main question was: “What makes the Lazy implementation better?”.</p><p>Well, let’s look at what advantages the Lazy implementation offers over the Eager or Classic one, but before we do, let’s remember what an Eager Singleton looks like.</p><h3>Eager Singleton</h3><p>As an example, we chose a class whose only task is to output a randomly generated string of a certain length to the console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*uYmwuTlcBN13QTkn" /><figcaption>Eager Singleton</figcaption></figure><p>An Eager implementation:</p><ol><li>Stores reference to the only existing object of the class in a <em>static final</em> field.</li><li>Limits the access level of the constructor to <em>private</em>, forbidding “foreign” classes from calling it.</li><li>Has a <em>public static</em> <em>getInstance()</em> method that returns a reference to the same object each time it is called.</li><li>* Some implementations of the Eager version allow direct access to the <em>INSTANCE</em> field, weakening its access level to <em>public</em>.</li></ol><h3>Initialization</h3><p>The nuance that matters most in the context of comparing the Eager and Lazy versions is at what point an instance is created. As you know, the <strong>values of static fields are written when a class is loaded</strong>. But what initiates the loading process?</p><p>There are 4 events that can serve as triggers to load the class:</p><ol><li><strong>Creating an object with the <em>new</em> operator.</strong><br>This event cannot be the trigger to load the <em>RandomPrinter</em> class, simply because the constructor of our printer is marked “private”, which prevents it from being used by “outside” classes.</li><li><strong>Loading a child class.</strong><br>Would also not be a reason to load our class, for exactly the same reason: a <em>private</em> constructor prohibits inheritance.</li><li><strong>Loading a class using the <em>Class.forName()</em> or <em>ClassLoader.loadClass()</em> method.</strong><br>It will definitely load our class and call its initialization, but it seems unrealistic as a standard approach to working with Singletons.</li><li><strong>Accessing a static method or variable.</strong><br>This looks like the most likely option, doesn’t it? Let’s consider it in more detail.</li></ol><p>Let’s imagine that we want to use our class for its intended purpose and print a random string. To do that, we need to get a <em>RandomPrinter</em> object. The only way to do so is to call the <em>getInstance()</em> method which, as mentioned in the <strong>point 4</strong>, will start the process of loading and initializing the class and will create a single <em>RandomPrinter</em> object.</p><p>It seems to be something like the idea of Lazy initialization, because the object was created exactly at the first request, isn’t it?</p><h3>Lazy Singleton</h3><p>Let’s implement a Lazy Singleton in its simplest form.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/0*-Skg7wXUXg_w5kQr" /><figcaption>Lazy Singleton</figcaption></figure><p>We only needed 2 changes to make the Singleton class Lazy:</p><ol><li>The <em>INSTANCE</em> field is no longer final, which allows you to not initialize it at declaration, but do it later.</li><li>The <em>getInstance()</em> method now checks if the <em>RandomPrinter</em> object has already been created and if not, creates it and returns it to the caller. If the object already exists, the reference to it is returned immediately and no new object is created.</li></ol><h3>So what’s the difference?</h3><p>Let’s go back to our object usage scenario. We want to print a random string again, again we call the <em>getInstance()</em> method, which… just like in the Eager Singleton, triggers the creation of the <em>RandomPrinter</em> object.</p><p>So what is the difference between the Eager and Lazy implementation in this case? The answer is simple: there is no difference!</p><p>In both cases, we need an object of the class. In fact, <em>RandomPrinter</em> doesn’t have any other use cases. All the client can ask our class to do is:</p><ol><li>Request a single object of the class using the <em>getInstance()</em> method.</li><li>Call the <em>printRandomString()</em> method on the received object.</li></ol><p>Thus, the client of our class needs the value of the <em>INSTANCE</em> field anyway, which means that <strong>it will be initialized whether our Singleton is Lazy or not</strong>. In other words, it makes absolutely no difference how we implement initialization: with or without <em>null</em> checking, any usage of the class will lead to the creation of a <em>RandomPrinter</em> object.</p><p>Consequently, any logic related to Lazy object creation in this case will only clutter the code and raise questions for its readers.</p><p>Of course, an extra <em>null</em> check added in the Lazy version and a non-final field will not significantly damage the functionality or readability of your code. However, if a class needs to be thread-safe, a trivial “<em>null</em> check” can easily turn into an unnecessary nested class or become a <em>synchronized</em> block with another redundant <em>null</em> reference check. None of this is good for your application or those who work on it with you, so, as they say:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-Q-KrosJFyp4rfHk" /><figcaption><a href="https://en.wikipedia.org/wiki/KISS_principle">https://en.wikipedia.org/wiki/KISS_principle</a></figcaption></figure><h3>Conclusion</h3><p>Certainly a Lazy implementation has its use cases. For example a Lazy Singleton class could have a <em>public static</em> variable or method that doesn’t require an instance to be used.</p><p>But <strong>if all use cases of your Singleton class require an instance to be created</strong>, then the Eager version will probably be a better choice.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af4aaaeb071f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/javarevisited/lazy-singleton-in-java-part-1-is-there-a-difference-af4aaaeb071f">Lazy vs Eager Singleton in Java</a> was originally published in <a href="https://medium.com/javarevisited">Javarevisited</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>