<?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: Helber Belmiro</title>
    <description>The latest articles on DEV Community by Helber Belmiro (@hbelmiro).</description>
    <link>https://dev.to/hbelmiro</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%2F522806%2Ffa8a7ed7-ffdc-430a-962e-cc0356957ceb.jpeg</url>
      <title>DEV Community: Helber Belmiro</title>
      <link>https://dev.to/hbelmiro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hbelmiro"/>
    <language>en</language>
    <item>
      <title>How to Create a Java Library: From Scratch to Maven Central</title>
      <dc:creator>Helber Belmiro</dc:creator>
      <pubDate>Thu, 15 Apr 2021 10:31:07 +0000</pubDate>
      <link>https://dev.to/hbelmiro/how-to-create-a-java-library-from-scratch-to-maven-central-2cfa</link>
      <guid>https://dev.to/hbelmiro/how-to-create-a-java-library-from-scratch-to-maven-central-2cfa</guid>
      <description>&lt;h1&gt;
  
  
  How to Create a Java library: From Scratch to Maven Central
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you usually need to rewrite or copy similar code between different projects, it may be time to stop replicating it and create a library.&lt;/p&gt;

&lt;p&gt;You can also share it as open-source so other people can use it and help you improve it.&lt;/p&gt;

&lt;p&gt;To use your library in different projects, you have to publish it on a repository like &lt;a href="https://search.maven.org" rel="noopener noreferrer"&gt;Maven Central Repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So let's run through the entire process and publish a library for padding Strings. We'll start by creating our project from scratch.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to skip the project creation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can use your own project and jump ahead to &lt;a href="//#preparing-pom.xml-to-deploy-on-maven-central"&gt;Preparing pom.xml to Deploy on Maven Central&lt;/a&gt;; or &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/hbelmiro/demo-library" rel="noopener noreferrer"&gt;Download my project from GitHub&lt;/a&gt; and jump ahead to Requesting Access to Maven Central.&lt;/p&gt;

&lt;p&gt;⚠️ IF YOU USE MY PROJECT, DON'T FORGET TO CHANGE ITS GROUP ID.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Creating the Project
&lt;/h2&gt;

&lt;p&gt;Run the following command on your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvn archetype:generate -DgroupId=com.thegreatapi.demolibrary -DartifactId=demolibrary -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use your own group ID on the command. If you use &lt;code&gt;com.thegreat.api.demolibrary&lt;/code&gt; you won't be able to publish to Maven Central.&lt;/p&gt;

&lt;p&gt;If you're not sure about what group ID to use, look at &lt;a href="https://central.sonatype.org/publish/requirements/coordinates/" rel="noopener noreferrer"&gt;this article&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;That command will create a project with the following &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="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
         &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.thegreatapi.demolibrary&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;demolibrary&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;1.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;demolibrary&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- FIXME change it to the project's website --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://www.example.com&lt;span class="nt"&gt;&amp;lt;/url&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;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;maven.compiler.source&amp;gt;&lt;/span&gt;1.7&lt;span class="nt"&gt;&amp;lt;/maven.compiler.source&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;maven.compiler.target&amp;gt;&lt;/span&gt;1.7&lt;span class="nt"&gt;&amp;lt;/maven.compiler.target&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;dependencies&amp;gt;&lt;/span&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;junit&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&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;4.11&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;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&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="c"&gt;&amp;lt;!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --&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;artifactId&amp;gt;&lt;/span&gt;maven-clean-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.1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --&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;artifactId&amp;gt;&lt;/span&gt;maven-resources-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.2&lt;span class="nt"&gt;&amp;lt;/version&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;plugin&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-compiler-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.8.0&lt;span class="nt"&gt;&amp;lt;/version&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;plugin&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;2.22.1&lt;span class="nt"&gt;&amp;lt;/version&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;plugin&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-jar-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.2&lt;span class="nt"&gt;&amp;lt;/version&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;plugin&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-install-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;2.5.2&lt;span class="nt"&gt;&amp;lt;/version&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;plugin&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-deploy-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;2.8.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --&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;artifactId&amp;gt;&lt;/span&gt;maven-site-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.7.1&lt;span class="nt"&gt;&amp;lt;/version&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;plugin&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-project-info-reports-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&lt;span class="nt"&gt;&amp;lt;/version&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;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's change it to use Java 11 instead of 1.7.&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;properties&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;maven.compiler.source&amp;gt;&lt;/span&gt;11&lt;span class="nt"&gt;&amp;lt;/maven.compiler.source&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;maven.compiler.target&amp;gt;&lt;/span&gt;11&lt;span class="nt"&gt;&amp;lt;/maven.compiler.target&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we create a &lt;code&gt;LICENSE&lt;/code&gt; file. I'll use Apache 2 License, but you can use any license you want. To use Apache 2 License, you have to copy the content from &lt;a href="http://www.apache.org/licenses/LICENSE-2.0.txt" rel="noopener noreferrer"&gt;http://www.apache.org/licenses/LICENSE-2.0.txt&lt;/a&gt; and paste it into your &lt;code&gt;LICENSE&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing the Library
&lt;/h2&gt;

&lt;p&gt;Now let's create an interface &lt;code&gt;StringPadder&lt;/code&gt; in the package &lt;code&gt;com.thegreatapi.demolibrary.stringpadder&lt;/code&gt;. That will be the interface that clients will use to pad Strings.&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.thegreatapi.demolibrary.stringpadder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Pads a {@link String}.
 * &amp;lt;p&amp;gt;
 * The instances of classes that implement this interface are thread-safe and immutable.
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;StringPadder&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Returns a new {@link String} that right-aligns the characters in the specified String by padding them with spaces
     * on the left, for a specified total length.
     *
     * @param stringToPad the {@link String} to be padded
     * @param totalLength total length of the new {@link String}
     * @return the padded {@link String}
     */&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;padLeft&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;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Returns a new {@link String} that right-aligns the characters in the specified String by padding them with the
     * specified char on the left, for a specified total length.
     *
     * @param stringToPad the {@link String} to be padded
     * @param totalLength total length of the new {@link String}
     * @return the padded {@link String}
     */&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;padLeft&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;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;paddingCharacter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Returns a new {@link String} that left-aligns the characters in the specified String by padding them with spaces
     * on the left, for a specified total length.
     *
     * @param stringToPad the {@link String} to be padded
     * @param totalLength total length of the new {@link String}
     * @return the padded {@link String}
     */&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;padRight&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;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Returns a new {@link String} that left-aligns the characters in the specified String by padding them with the
     * specified char on the left, for a specified total length.
     *
     * @param stringToPad the {@link String} to be padded
     * @param totalLength total length of the new {@link String}
     * @return the padded {@link String}
     */&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;padRight&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;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;paddingCharacter&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 let's create the implementation of the &lt;code&gt;StringPadder&lt;/code&gt; interface.&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.thegreatapi.demolibrary.stringpadder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StringPadderImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;StringPadder&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;StringPadderImpl&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;padLeft&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;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;padLeft&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalLength&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="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;padLeft&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;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;paddingCharacter&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getStringToBeAdded&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paddingCharacter&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;stringToPad&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;padRight&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;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;padRight&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalLength&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="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;padRight&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;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;paddingCharacter&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;stringToPad&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;getStringToBeAdded&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paddingCharacter&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="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getStringToBeAdded&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;stringToPad&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;paddingCharacter&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;totalLength&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;stringToPad&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Character&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;paddingCharacter&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;repeat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&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;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the class is package-private, so the clients can't use it in their code.&lt;/p&gt;

&lt;p&gt;Now we're going to create a factory for clients to create instances of &lt;code&gt;StringPadder&lt;/code&gt;.&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.thegreatapi.demolibrary.stringpadder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Factory for creating instances of {@link StringPadder}.
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StringPadderFactory&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;StringPadderFactory&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="cm"&gt;/**
     * Creates an instance of {@link StringPadder}.
     *
     * @return the new instance
     */&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;StringPadder&lt;/span&gt; &lt;span class="nf"&gt;createStringPadder&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;StringPadderImpl&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;h2&gt;
  
  
  Creating Tests
&lt;/h2&gt;

&lt;p&gt;Let's replace JUnit 4 with JUnit 5 and add AssertJ dependency to our &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;dependencies&amp;gt;&lt;/span&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&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.7.1&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;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.assertj&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;assertj-core&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.19.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;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we're ready to implement our tests.&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.thegreatapi.demolibrary.stringpadder&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;org.junit.jupiter.api.Test&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;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StringPadderImplTest&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;StringPadderImpl&lt;/span&gt; &lt;span class="n"&gt;stringPadder&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;StringPadderImpl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;padLeft&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringPadder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;padLeft&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"     thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;padLeftWithZeros&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringPadder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;padLeft&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"00000thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;padRight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringPadder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;padRight&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com     "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;padRightWithZeros&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringPadder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;padRight&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com00000"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;padLeftWithInvalidTotalLength&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringPadder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;padLeft&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;padLeftWithZerosInvalidTotalLength&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringPadder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;padLeft&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;padRightInvalidTotalLength&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringPadder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;padRight&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;padRightWithZerosInvalidTotalLength&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringPadder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;padRight&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"thegreatapi.com"&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 &lt;code&gt;mvn verify&lt;/code&gt;, we should see an output similar to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home/bin/java -Dmaven.multiModuleProjectDirectory=/Users/helber/Desktop/demolibrary -Dmaven.home=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3 -Dclassworlds.conf=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/bin/m2.conf -Dmaven.ext.class.path=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven-event-listener.jar -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=61185:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/boot/plexus-classworlds.license:/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/boot/plexus-classworlds-2.6.0.jar org.codehaus.classworlds.Launcher -Didea.version=2020.3.3 verify
[INFO] Scanning for projects...
[INFO] 
[INFO] --------------&amp;lt; com.thegreatapi.demolibrary:demolibrary &amp;gt;---------------
[INFO] Building demolibrary 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ demolibrary ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/helber/Desktop/demolibrary/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ demolibrary ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /Users/helber/Desktop/demolibrary/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ demolibrary ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/helber/Desktop/demolibrary/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ demolibrary ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/helber/Desktop/demolibrary/target/test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ demolibrary ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.thegreatapi.demolibrary.stringpadder.StringPadderImplTest
[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.07 s - in com.thegreatapi.demolibrary.stringpadder.StringPadderImplTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] 
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ demolibrary ---
[INFO] Building jar: /Users/helber/Desktop/demolibrary/target/demolibrary-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.378 s
[INFO] Finished at: 2021-04-05T06:36:12-03:00
[INFO] ------------------------------------------------------------------------

Process finished with exit code 0

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

&lt;/div&gt;



&lt;p&gt;Our implementation is ready. The next step is to deploy our library to Maven Central.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparing pom.xml to Deploy on Maven Central {#preparing-pom.xml-to-deploy-on-maven-central}
&lt;/h2&gt;

&lt;p&gt;There are some requirements we need to satisfy in order to upload our library to Maven Central. We can find those requirements on &lt;a href="https://central.sonatype.org/pages/requirements.html" rel="noopener noreferrer"&gt;https://central.sonatype.org/pages/requirements.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first thing we have to change in our &lt;code&gt;pom.xml&lt;/code&gt; is to define a non-SNAPSHOT version for our library. To do that, we just need to remove the &lt;code&gt;-SNAPSHOT&lt;/code&gt; suffix. Let's define our version as &lt;code&gt;0.0.1&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;version&amp;gt;&lt;/span&gt;0.0.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we have to add a description and a URL to our project. In my case, the URL should be &lt;a href="http://thegreatapi.com" rel="noopener noreferrer"&gt;http://thegreatapi.com&lt;/a&gt;. Your URL must differ from mine because you have to own the domain. You can also use a GitHub URL if you prefer.&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;description&amp;gt;&lt;/span&gt;
    This project is a library for padding Strings in Java.
    DON'T USE THIS IN PRODUCTION. IT WAS CREATED FOR DEMO PURPOSES ONLY.
&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://thegreatapi.com&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we add the license information. Note that I'm using Apache 2 license. Use the same license that you defined in your &lt;code&gt;LICENSE&lt;/code&gt; file.&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;licenses&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;license&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;The Apache License, Version 2.0&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://www.apache.org/licenses/LICENSE-2.0.txt&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/license&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/licenses&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to add information about the developers.&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;developers&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;developer&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Helber Belmiro&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;email&amp;gt;&lt;/span&gt;your@email.com&lt;span class="nt"&gt;&amp;lt;/email&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;organization&amp;gt;&lt;/span&gt;The Great API&lt;span class="nt"&gt;&amp;lt;/organization&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;organizationUrl&amp;gt;&lt;/span&gt;https://thegreatapi.com&lt;span class="nt"&gt;&amp;lt;/organizationUrl&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/developer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/developers&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then, add the information about the Source Code Management (SCM). The following information is for my project. Replace it with your project's information.&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;scm&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;connection&amp;gt;&lt;/span&gt;scm:git:git@github.com:hbelmiro/demo-library.git&lt;span class="nt"&gt;&amp;lt;/connection&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;developerConnection&amp;gt;&lt;/span&gt;scm:git:ssh://github.com:hbelmiro/demo-library.git&lt;span class="nt"&gt;&amp;lt;/developerConnection&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://github.com/hbelmiro/demo-library/tree/master&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/scm&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maven Central demands you to send the Javadoc and source code. So you have to create it when building your artifacts. You must also sign the artifacts you are sending to Maven Central.&lt;/p&gt;

&lt;p&gt;Since we need to do it only when deploying to Maven Central, it might be a good idea to create a profile for this.&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;profiles&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;profile&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;release&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;activation&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;performRelease&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/activation&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;build&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-gpg-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;1.6&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;sign-artifacts&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;verify&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;sign&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/executions&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;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-javadoc-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.2.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;attach-javadocs&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;jar&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;javadocExecutable&amp;gt;&lt;/span&gt;${java.home}/bin/javadoc&lt;span class="nt"&gt;&amp;lt;/javadocExecutable&amp;gt;&lt;/span&gt;
                    &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;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-source-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.2.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;attach-sources&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;jar-no-fork&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/executions&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;/build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/profile&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/profiles&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also have to install a GPG client and put it on your command line path. Follow the instructions on &lt;a href="https://central.sonatype.org/pages/working-with-pgp-signatures.html" rel="noopener noreferrer"&gt;https://central.sonatype.org/pages/working-with-pgp-signatures.html&lt;/a&gt; to install the GPG client.&lt;/p&gt;

&lt;p&gt;The next step is to add the Distribution Management to your &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;distributionManagement&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;snapshotRepository&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;ossrh&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://s01.oss.sonatype.org/content/repositories/snapshots&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/snapshotRepository&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;ossrh&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/distributionManagement&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, add nexus-staging-maven-plugin.&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.sonatype.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;nexus-staging-maven-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;1.6.7&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;extensions&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/extensions&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;serverId&amp;gt;&lt;/span&gt;ossrh&lt;span class="nt"&gt;&amp;lt;/serverId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;nexusUrl&amp;gt;&lt;/span&gt;https://s01.oss.sonatype.org/&lt;span class="nt"&gt;&amp;lt;/nexusUrl&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;autoReleaseAfterClose&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/autoReleaseAfterClose&amp;gt;&lt;/span&gt;
                &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;Your library is ready to be published to Maven Central.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requesting Access to Maven Central
&lt;/h2&gt;

&lt;p&gt;Using the OSS Repository Hosting (OSSRH), provided by Sonatype for any open-source project, is the easiest way to publish your project.&lt;/p&gt;

&lt;p&gt;The first step is to &lt;a href="https://issues.sonatype.org/secure/Signup!default.jspa" rel="noopener noreferrer"&gt;create a JIRA account&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After that, you have to &lt;a href="https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&amp;amp;pid=10134" rel="noopener noreferrer"&gt;create a New Project ticket&lt;/a&gt;. As an example, you can use &lt;a href="https://issues.sonatype.org/browse/OSSRH-66416" rel="noopener noreferrer"&gt;the ticket I opened&lt;/a&gt; to publish demolibrary.&lt;/p&gt;

&lt;p&gt;Officially, they ask you for 2 working days to complete the process, but it normally takes one or two hours.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use your own group ID. If you use &lt;code&gt;com.thegreat.api.demolibrary&lt;/code&gt; you won't be able to publish to Maven Central.&lt;/p&gt;




&lt;p&gt;They will ask if you own the domain specified on groupId and if so, you'll have to verify the ownership. On my ticket they commented:&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%2Fthegreatapi.com%2Fwp-content%2Fuploads%2F2021%2F04%2Fcomment_jira_ticket.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%2Fthegreatapi.com%2Fwp-content%2Fuploads%2F2021%2F04%2Fcomment_jira_ticket.png" alt="Comment posted by Central OSSRH about the domain ownership."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my case, I added a TXT record to my DNS. When I did that, I commented on the ticket, and they set the ticket to "Resolved".&lt;/p&gt;

&lt;h2&gt;
  
  
  Releasing the Library
&lt;/h2&gt;

&lt;p&gt;After proving the domain ownership, you're ready to upload your artifacts. To do that, you first release it to staging.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mvn clean deploy -P release&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;At this point, your artifacts are stored in a private repository, so you can verify them before releasing them. So log in to &lt;a href="https://s01.oss.sonatype.org/" rel="noopener noreferrer"&gt;https://s01.oss.sonatype.org/&lt;/a&gt; using your JIRA credentials.&lt;/p&gt;

&lt;p&gt;On the left menu, click on "Staging Repositories" and you'll see your library.&lt;/p&gt;

&lt;p&gt;If everything is OK with your library, you can close it, otherwise, you can drop it.&lt;/p&gt;

&lt;p&gt;When you close it, on the low section, you can check if it was closed successfully by clicking on the "Activity" tab. You should see something similar to this:&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%2Fthegreatapi.com%2Fwp-content%2Fuploads%2F2021%2F04%2Frepository_closed.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%2Fthegreatapi.com%2Fwp-content%2Fuploads%2F2021%2F04%2Frepository_closed.png" alt="Repository closed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the repository was successfully closed, now you're able to promote it to release. &lt;/p&gt;

&lt;p&gt;Run the following command using your Repository ID. On the image above, it's &lt;code&gt;comthegreatapidemolibrary-1005&lt;/code&gt;. &lt;strong&gt;Don't forget to replace it with your own ID&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mvn nexus-staging:release -DstagingRepositoryId=comthegreatapidemolibrary-1005&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use your own group ID. If you use &lt;code&gt;com.thegreat.api.demolibrary&lt;/code&gt; you won't be able to publish to Maven Central.&lt;/p&gt;




&lt;p&gt;You should see an output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INFO]  * Connected to Nexus at https://s01.oss.sonatype.org:443/, is version 2.14.20-02 and edition "Professional"
[INFO] Releasing staging repository with IDs=[comthegreatapidemolibrary-1005]

Waiting for operation to complete...
.........

[INFO] Released
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  28.583 s
[INFO] Finished at: 2021-04-07T07:53:50-03:00
[INFO] ------------------------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your library is published. On this very first deployment, you have to comment on the JIRA ticket, so they can activate the sync to Maven Central.&lt;/p&gt;

&lt;p&gt;After Sonatype activates Maven Central sync for your library, when you successfully release new components, they will be published to Central &lt;a href="https://repo1.maven.org/maven2/" rel="noopener noreferrer"&gt;https://repo1.maven.org/maven2/&lt;/a&gt;, typically within 10 minutes, though updates to &lt;a href="https://search.maven.org" rel="noopener noreferrer"&gt;https://search.maven.org&lt;/a&gt; can take up to two hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start Your Library Now
&lt;/h2&gt;

&lt;p&gt;You are now ready to start your own library. It will be great for you and the Java community.&lt;/p&gt;

&lt;p&gt;To help you with that, I wrote an article about &lt;a href="https://thegreatapi.com/blog/3-principles-for-java-engineers-apply-in-their-apis-to-stay-up-to-date-with-technology/" rel="noopener noreferrer"&gt;the principles that sustain great frameworks and libraries&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you still don't feel prepared, what's preventing you from taking the next step? Comment here or send me a message on &lt;a href="https://thegreatapi.com/social-media/" rel="noopener noreferrer"&gt;my social media&lt;/a&gt;. I'll be happy to help you.&lt;/p&gt;

</description>
      <category>java</category>
      <category>maven</category>
      <category>library</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>4 Mistakes That Prevent Your Java APIs From Having More Users</title>
      <dc:creator>Helber Belmiro</dc:creator>
      <pubDate>Thu, 18 Mar 2021 10:49:28 +0000</pubDate>
      <link>https://dev.to/hbelmiro/4-mistakes-that-prevent-your-java-apis-from-having-more-users-3oi1</link>
      <guid>https://dev.to/hbelmiro/4-mistakes-that-prevent-your-java-apis-from-having-more-users-3oi1</guid>
      <description>&lt;p&gt;When you have more people using your Java APIs, your projects grow and naturally you become a better engineer. You become more likely to increase your incomes and join great new projects. It also enables people to get their jobs done faster. So it’s a win-win situation.&lt;/p&gt;

&lt;p&gt;To keep those people who already use your API and attract more, you need to eliminate these 4 mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake 1: Force the Clients to Write Bad Code.
&lt;/h2&gt;

&lt;p&gt;In his excellent book “&lt;a href="https://www.amazon.com/gp/product/B009NNXPES/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B009NNXPES&amp;amp;linkCode=as2&amp;amp;tag=hbelmiro0f-20&amp;amp;linkId=b7b2b5887c2f9972587e7f53b8f28442" rel="noopener noreferrer"&gt;20 API Paradoxes&lt;/a&gt;”, Jaroslav Tulach does an analogy of developers to artists. For both artists and developers, the beauty of their art matters. We like to look at our code and see beauty. So, when you force your users to create unpleasant or error-prone code, they get disappointed and frustrated.&lt;/p&gt;

&lt;p&gt;An example of an API that forces the client to write bad code is the interface &lt;code&gt;org.osgi.framework.Bundle&lt;/code&gt;. It provides us the method &lt;code&gt;getLocation()&lt;/code&gt; which returns a &lt;code&gt;String&lt;/code&gt; value. The problem is it doesn’t specify a format for that value, and it’s the only method that can provide the bundle’s location. As the API doesn’t specify a format, the implementation is free to use anyone.&lt;/p&gt;

&lt;p&gt;As you can see on the following image, the Equinox OSGi implementation returns the location in a way that the clients need to parse the value to find the file.&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/http%3A%2F%2Fthegreatapi.com%2Fwp-content%2Fuploads%2F2021%2F03%2F3937cb699b74fc0cf160d7584edb01fbxxl.jpg" 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/http%3A%2F%2Fthegreatapi.com%2Fwp-content%2Fuploads%2F2021%2F03%2F3937cb699b74fc0cf160d7584edb01fbxxl.jpg" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the clients have two problems:&lt;/p&gt;

&lt;p&gt;1) The API is forcing them to create an implementation lock-in. The clients depend on how the implementation formats the location.&lt;/p&gt;

&lt;p&gt;2) The API is forcing them to create a version lock-in. The format can vary between the different versions of the implementation.&lt;/p&gt;

&lt;p&gt;The API designers could solve that problem by adding to the &lt;code&gt;Bundle&lt;/code&gt; interface a method that returns a &lt;code&gt;Path&lt;/code&gt; or &lt;code&gt;File&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another solution could be to make the &lt;code&gt;getLocation()&lt;/code&gt; method originally return a &lt;code&gt;Location&lt;/code&gt; class, and that &lt;code&gt;Location&lt;/code&gt; could have the attributes needed. That solution would let explicit what the implementation must return and would not force the clients to parse a &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake 2: Lack of Consistency in Nomenclature.
&lt;/h2&gt;

&lt;p&gt;One of the &lt;a href="https://thegreatapi.com/blog/3-principles-for-java-engineers-apply-in-their-apis-to-stay-up-to-date-with-technology/" rel="noopener noreferrer"&gt;3 principles that sustain great frameworks and libraries&lt;/a&gt; is about ease of use. If your API is hard to use, you’re losing clients.&lt;/p&gt;

&lt;p&gt;When you don’t have a standard for naming classes and interfaces, your API becomes hard to use. Don’t mix different names that have the same meaning in your API.&lt;/p&gt;

&lt;p&gt;For example, the words “fetch”, “retrieve” and “get”. All of them have the same meaning. By mixing them, the clients won’t know how to search for a method, because sometimes you use “retrieve”, sometimes “fetch”, and sometimes “get”. So choose one of them and stick with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake 3: Centralize Access to the Features in a Single Class
&lt;/h2&gt;

&lt;p&gt;We may think that by centralizing access to our API’s features in a super class, we would make the client’s life easier. At first, it seems a good idea, since after all, all the clients need to do to access a feature is to call an inherited method.&lt;/p&gt;

&lt;p&gt;Let’s look at an example to see it clearer.&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreatApi&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;CoolFeature&lt;/span&gt; &lt;span class="nf"&gt;getCoolFeature&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;CoolFeature&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;NiceFeature&lt;/span&gt; &lt;span class="nf"&gt;getNiceFeature&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;NiceFeature&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;AwesomeFeature&lt;/span&gt; &lt;span class="nf"&gt;getAwesomeFeature&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;AwesomeFeature&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 js-code-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;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreatApiClient&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;GreatApi&lt;/span&gt; &lt;span class="n"&gt;greatApi&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;GreatApi&lt;/span&gt; &lt;span class="nf"&gt;getGreatApi&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;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;greatApi&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 js-code-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;ClientClass&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;GreatApiClient&lt;/span&gt; &lt;span class="o"&gt;{&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;doClientStuff&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;getGreatApi&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAwesomeFeature&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;doAwesomeStuff&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;Straightforward for the client to use the feature, right? But that approach will bring us tremendous problems in the future.&lt;/p&gt;

&lt;p&gt;One problem is that every client class that needs to use the API will depend on &lt;code&gt;GreatApiClient&lt;/code&gt; and &lt;code&gt;GreatApi&lt;/code&gt; classes. We don’t want that because the more spread out an artifact is, the more difficult is to change it.&lt;/p&gt;

&lt;p&gt;Testing also would become difficult because the client would end up having to mock many classes.&lt;/p&gt;

&lt;p&gt;Another problem is that the &lt;code&gt;GreatApi&lt;/code&gt; class would become huge because the access to all the API’s features would be made through that class. Besides violating the &lt;a href="https://en.wikipedia.org/wiki/Single-responsibility_principle" rel="noopener noreferrer"&gt;Single-responsibility principle&lt;/a&gt;, this would bring concurrency problems as well.&lt;/p&gt;

&lt;p&gt;An excellent alternative to that is to use dependency injection instead of having the classes &lt;code&gt;GreatApi&lt;/code&gt; and &lt;code&gt;GreatApiClient&lt;/code&gt;. This way, the client class would depend only on the classes that it really needs.&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.inject.Inject&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;class&lt;/span&gt; &lt;span class="nc"&gt;ClientClassUsingDependencyInjection&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;AwesomeFeature&lt;/span&gt; &lt;span class="n"&gt;awesomeFeature&lt;/span&gt;&lt;span class="o"&gt;;&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;doClientStuff&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;awesomeFeature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doAwesomeStuff&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;h2&gt;
  
  
  Mistake 4: Don’t Use Immutable Objects
&lt;/h2&gt;

&lt;p&gt;Immutable classes are thread-safe. That alone is a good argument for writing immutable classes. But there are more advantages to using those classes.&lt;/p&gt;

&lt;p&gt;Joshua Bloch states in his “&lt;a href="https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0134685997&amp;amp;linkCode=as2&amp;amp;tag=hbelmiro0f-20&amp;amp;linkId=213790c63c0d57baac2e45b3183a35b2" rel="noopener noreferrer"&gt;Effective Java&lt;/a&gt;” book:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An immutable class is simply a class whose instances cannot be modified. All of the information contained in each instance is fixed for the lifetime of the object, so no changes can ever be observed. The Java platform libraries contain many immutable classes, including &lt;code&gt;String&lt;/code&gt;, the boxed primitive classes, and &lt;code&gt;BigInteger&lt;/code&gt; and &lt;code&gt;BigDecimal&lt;/code&gt;. There are many good reasons for this: Immutable classes are easier to design, implement, and use than mutable classes. They are less prone to error and are more secure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can find out how to create immutable classes in &lt;a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html" rel="noopener noreferrer"&gt;Oracle’s Java Tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enable Your Clients to Enjoy Using Your API
&lt;/h2&gt;

&lt;p&gt;Having good performance and being bug-free is fundamental for a great API. This is not what will make you have more people using your Java APIs. This is the minimum that people expect. Do more than just that. Make your clients happy by using your API. They want to create great code, so don’t force them to use bad practices. Instead, use your API to encourage and inspire them to use the best practices.&lt;/p&gt;

&lt;p&gt;This will help you become a better professional and will empower you to grow your career.&lt;/p&gt;

&lt;p&gt;What’s preventing you from having more people using your Java APIs? Leave a comment here or send me a message on &lt;a href="https://thegreatapi.com/social-media/" rel="noopener noreferrer"&gt;my social media&lt;/a&gt;. It will be great to help you attract more clients to your product.&lt;/p&gt;

</description>
      <category>java</category>
      <category>apidesign</category>
      <category>api</category>
      <category>career</category>
    </item>
    <item>
      <title>3 principles for Java Engineers to apply in their APIs and stay up-to-date with technology</title>
      <dc:creator>Helber Belmiro</dc:creator>
      <pubDate>Wed, 24 Feb 2021 15:13:17 +0000</pubDate>
      <link>https://dev.to/hbelmiro/3-principles-for-java-engineers-apply-in-their-apis-to-stay-up-to-date-with-technology-2j4c</link>
      <guid>https://dev.to/hbelmiro/3-principles-for-java-engineers-apply-in-their-apis-to-stay-up-to-date-with-technology-2j4c</guid>
      <description>&lt;p&gt;(This post originally appeared on &lt;a href="https://thegreatapi.com/blog/3-principles-for-java-engineers-apply-in-their-apis-to-stay-up-to-date-with-technology/"&gt;my blog&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Java Engineers can adopt several strategies to stay up-to-date with technology. One of the most natural ones is by developing frameworks and libraries. By doing that, they often find themselves in one of these two situations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Any significant change in their code would break their client’s applications. So, they struggle with releasing extra features. Most of their releases comprise only minor bug fixes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Although they often release versions containing extra features, their clients never upgrade. Upgrading to the recent version would take too much effort, and the clients don’t have the time for that.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you find yourself in one of those situations, you need to know the 3 principles that sustain great frameworks and libraries. Applying these principles in your APIs will put you on the path to staying up-to-date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principle 1 — Enable Your Clients To Start Fast
&lt;/h2&gt;

&lt;p&gt;What do you do when you try a new framework or library?&lt;/p&gt;

&lt;p&gt;Do you read the entire documentation learning the theory before starting coding? Or you just find a simple use-case and then change and experiment?&lt;/p&gt;

&lt;p&gt;Most developers prefer the second option. They don’t want to read much documentation. They just want to get their things done.&lt;/p&gt;

&lt;p&gt;When you think about their managers, it’s the same. Managers want a short Time To Market. They want their software running in production in the shortest time possible.&lt;/p&gt;

&lt;p&gt;To achieve that, create APIs that are easy to understand by doing a quick look at the classes and methods. Try to keep them simple and give them meaningful names.&lt;/p&gt;

&lt;p&gt;Besides that, also add use-cases to the documentation. Most popular frameworks have guides like that.&lt;/p&gt;

&lt;p&gt;By having access to use-cases, the developer can find the one he needs and adapt it. Often, that’s all he needs to get his things done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principle 2 — Keep Your Product Up-To-Date With The Market Trends
&lt;/h2&gt;

&lt;p&gt;Developers don’t enjoy working with uncool stuff. They want to use the coolest technologies and share their knowledge with other developers. They like people to see them as ones who know a lot of cool stuff.&lt;/p&gt;

&lt;p&gt;That’s important because people need to know your product, or else nobody will use it. And being cool, it’ll have free and genuine publicity.&lt;/p&gt;

&lt;p&gt;So, what makes a framework or library cool? Besides being easy to get started with (Principle 1), it has to be modern and up-to-date with the market trends, releasing additional features with consistency.&lt;/p&gt;

&lt;p&gt;If you do that, you’ll also stay up-to-date with the new stuff. So everyone wins. But you have to do it right. That’s why you need to know the third and most important principle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principle 3 — Enable Your Clients to Upgrade With Ease
&lt;/h2&gt;

&lt;p&gt;Total Cost of Ownership (TCO) is the price a client pays for a product, plus the price he pays to keep it up and running. That’s important because it’s connected with both previous principles.&lt;/p&gt;

&lt;p&gt;It connects with Principle 1 because the clients want to save money always as possible. They don’t want to spend much money to have their applications up and running.&lt;/p&gt;

&lt;p&gt;It also connects with Principle 2 because your product has to be cool. At some point, your clients will need the additional features you’ve been releasing.&lt;/p&gt;

&lt;p&gt;But just being cool isn’t enough. It also has to be backward compatible. Otherwise, the clients will need to change their applications when upgrading, and this will take time and money.&lt;/p&gt;

&lt;p&gt;Keeping backward compatibility is essential for a lasting product. Once your clients use your APIs, you can’t change them anymore. That’s why you need to design them carefully. Do it in a way that allows you to evolve without breaking the client’s applications.&lt;/p&gt;

&lt;p&gt;How do you do that? Define specific use-cases, as mentioned in Principle 1, and the early versions of your APIs shouldn’t be too flexible. Flexibility is inversely proportional to evolution with backward compatibility. So start rigid and then escalate the flexibility. Also, prefer to use final methods and classes whenever you can.&lt;/p&gt;

&lt;p&gt;You should also create high-cohesion and low-coupling artifacts. Remember that the more spread out an artifact is, the more difficult is to change it.&lt;/p&gt;

&lt;p&gt;And the most important tip I can give you for keeping backward compatibility is to encapsulate the internals. Make everything private and expose only the essential classes and methods that the client needs to use. Besides decreasing complexity, this will allow you to make changes without breaking compatibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apply The 3 Principles Now And Unlock Your Career
&lt;/h2&gt;

&lt;p&gt;Being able to apply the three principles of great frameworks and librariesin your APIs will certainly help you work with new technologies. It’s a must for you to evolve your product with consistency.&lt;/p&gt;

&lt;p&gt;Now it’s up to you.&lt;/p&gt;

&lt;p&gt;What’s the biggest challenge you’re facing right now about designing or maintaining an API? What’s preventing you from applying those principles and staying up-to-date with the new technologies?&lt;/p&gt;

&lt;p&gt;Leave a comment or &lt;a href="http://twitter.com/helber_belmiro"&gt;send me a message on Twitter&lt;/a&gt;. I’ll be happy to help you overcome this challenge.&lt;/p&gt;

</description>
      <category>java</category>
      <category>apidesign</category>
      <category>api</category>
      <category>career</category>
    </item>
  </channel>
</rss>
