<?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: Ruby Valappil</title>
    <description>The latest articles on DEV Community by Ruby Valappil (@rubyshiv).</description>
    <link>https://dev.to/rubyshiv</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%2F809571%2Fb36ca46b-a4e2-4a71-9f2c-ba049d06d61c.jpg</url>
      <title>DEV Community: Ruby Valappil</title>
      <link>https://dev.to/rubyshiv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rubyshiv"/>
    <language>en</language>
    <item>
      <title>Java Instrumentation — A Simple Working Example in Java</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Fri, 25 Mar 2022 15:34:03 +0000</pubDate>
      <link>https://dev.to/rubyshiv/java-instrumentation-a-simple-working-example-in-java-4adm</link>
      <guid>https://dev.to/rubyshiv/java-instrumentation-a-simple-working-example-in-java-4adm</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/javarevisited/java-instrumentation-a-simple-working-example-in-java-a2c549024d9c?source=rss-116212d41081------2" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2600%2F1%2ASNaQhsa09bU0XS9DC_sHyw.jpeg" alt="Java instrumentation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, we will explore how to instrument a Java program.&lt;/p&gt;

&lt;p&gt;Java package that provides services to allow instrumentation is java.lang.instrument.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Instrumentation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;From the docs — “The mechanism for instrumentation is modification of the byte-codes of methods.”&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In simple words, we know that when we run our Java programs it gets converted to bytecode. These are then loaded to JVM using classloaders. Using Instrumentation APIs we get to modify the bytecodes of these programs at runtime.&lt;/p&gt;

&lt;p&gt;Application monitoring tools use this same service to provide useful information on execution time etc.&lt;/p&gt;

&lt;p&gt;The class that intercepts the bytecode is called an Agent Class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Know the Components&lt;/strong&gt;&lt;br&gt;
The main components are,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent Class — It’s similar to the main class of a Java application. This class must contain a method named premain().
premain() method can have one of two possible signatures,&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 the docs-
public static void premain(String agentArgs, Instrumentation inst);
public static void premain(String agentArgs);

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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Transformer Class — This class implements the ClassFileTransformer interface and implements the transform method.&lt;br&gt;
&lt;code&gt;public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined,&lt;br&gt;
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manifest file — While creating a jar of a java application, we provide the path to the main class in the manifest file, similarly in the java agent (agent class + transformer class) we need to create a manifest file and add the path to the class that has the premain method.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What’s in the Java Instrument package&lt;/strong&gt;&lt;br&gt;
java.lang.instrument package provides two Interfaces,&lt;br&gt;
ClassFileTransformer — This is implemented by a Java Agent Class.&lt;/p&gt;

&lt;p&gt;Instrumentation — Provides services needed to perform instrumentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Implement?&lt;/strong&gt;&lt;br&gt;
A few third-party libraries are available in the market to perform operations on the bytecode. In this example, we will use javassist but you can achieve similar results using other libraries as well.&lt;/p&gt;

&lt;p&gt;maven dependency to add javassist to our project is,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 https://mvnrepository.com/artifact/org.javassist/javassist --&amp;gt;
&amp;lt;dependency&amp;gt;
&amp;lt;groupId&amp;gt;org.javassist&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;javassist&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;3.27.0-GA&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;

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

&lt;/div&gt;

&lt;p&gt;In this tutorial, we will create two projects,&lt;br&gt;
Our Main Application — that prints a Welcome message.&lt;br&gt;
Our Java Agent — that prints a String value after our application is done printing the welcome message.&lt;/p&gt;

&lt;p&gt;We will also be using maven to build our java applications. You may want to create a simple java application without using build tools and create a jar using the java jar command.&lt;/p&gt;

&lt;p&gt;I prefer using the build tool so as to not worry about providing the path to third-party dependencies or creating the manifest file.&lt;/p&gt;

&lt;p&gt;Step 1: Let’s create a maven project and print a welcome message. This would be our main application.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 myapp;
public class Sample {
public static void main(String[] args) {
System.out.println("Hey There");
}
}}

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

&lt;/div&gt;

&lt;p&gt;As we will be running the agent and our application from the command line, let’s give the path to the main class in the pom file(the equivalent of adding manifest file) and add maven-jar-plugin to generate a jar.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;artifactId&amp;gt;maven-jar-plugin&amp;lt;/artifactId&amp;gt;&lt;br&gt;
...&lt;br&gt;
&amp;lt;manifest&amp;gt;&lt;br&gt;
&amp;lt;addClasspath&amp;gt;true&amp;lt;/addClasspath&amp;gt;&lt;br&gt;
&amp;lt;mainClass&amp;gt;myapp.Sample&amp;lt;/mainClass&amp;gt;&lt;br&gt;
&amp;lt;/manifest&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Step 2: Next, let’s create our second maven project. This would be our Java Agent.&lt;br&gt;
Add a class that would implement the ClassFileTransformer. In this class, we will use the services provided by javaassist library and read the byte array of the class that class loader loads, and add our own features on top of it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 instrumentation to Sample class alone
if (className.equals("myapp/Sample")) {
try {
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));
CtMethod[] methods = ctClass.getDeclaredMethods();
for (CtMethod method : methods) {
method.insertAfter("System.out.println(\"adding end line..\");");
}
byteCode = ctClass.toBytecode();
ctClass.detach();
} catch (Throwable ex) {
System.out.println("Exception: " + ex);
ex.printStackTrace();
}
}

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

&lt;/div&gt;

&lt;p&gt;In the above example, we read the method from our main application and then add an extra feature after the method is executed.&lt;/p&gt;

&lt;p&gt;We also need to create a class that would contain the premain method.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 static void premain(String args, Instrumentation instr) {
System.out.println("Inside premain.........");
instr.addTransformer(new MyTransformer());
}

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

&lt;/div&gt;

&lt;p&gt;We also need to make sure that we use maven assembly and not jar plugin. &lt;br&gt;
&lt;code&gt;&amp;lt;artifactId&amp;gt;maven-assembly-plugin&amp;lt;/artifactId&amp;gt;&lt;/code&gt;&lt;br&gt;
assembly plugin will make sure that all the third party dependencies are bundled together with the application class files. If we add a jar plugin, dependencies will not be bundled with the class files and we would get classnotfound exceptions for all the classes that are in javaassist library.&lt;/p&gt;

&lt;p&gt;Also, we need to add the path to premain() class in the manifest entry of pom file.&lt;br&gt;
&lt;code&gt;&amp;lt;archive&amp;gt;&lt;br&gt;
&amp;lt;manifest&amp;gt;&lt;br&gt;
&amp;lt;addDefaultImplementationEntries&amp;gt;&lt;br&gt;
true&amp;lt;/addDefaultImplementationEntries&amp;gt;&lt;br&gt;
&amp;lt;addDefaultSpecificationEntries&amp;gt;&lt;br&gt;
true&amp;lt;/addDefaultSpecificationEntries&amp;gt;&lt;br&gt;
&amp;lt;/manifest&amp;gt;&lt;br&gt;
&amp;lt;manifestEntries&amp;gt;&lt;br&gt;
&amp;lt;Premain-Class&amp;gt;agent.MyAgent&amp;lt;/Premain-Class&amp;gt;&lt;br&gt;
&amp;lt;Can-Redefine-Classes&amp;gt;false&amp;lt;/Can-Redefine-Classes&amp;gt;&lt;br&gt;
&amp;lt;Can-Retransform-Classes&amp;gt;true&amp;lt;/Can-Retransform-Classes&amp;gt;&lt;br&gt;
&amp;lt;/manifestEntries&amp;gt;&lt;br&gt;
&amp;lt;/archive&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once the changes are made, build the jar files of both applications.&lt;br&gt;
Testing&lt;br&gt;
Once the jars are generated, run the below command and check the output&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;
 &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;javaagent:&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="no"&gt;SNAPSHOT&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;jar&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jar&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;jar&lt;/span&gt; &lt;span class="n"&gt;myapp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="no"&gt;SNAPSHOT&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jar&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;output would be&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 premain.........
Hey There
adding end line..

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

&lt;/div&gt;

&lt;p&gt;As expected, we see that the premain method was executed first, which adds the transformer, when the classloader loads our main application, it appends the print statement that the transformer instructed to add after the method is executed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Complete agent and application code is available over &lt;a href="https://github.com/rubykv/code-examples/tree/master/java-instrumentation" rel="noopener noreferrer"&gt;Github&lt;/a&gt;. If you find the code useful, leave a star ⭐️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://javapapers.com/core-java/java-instrumentation/116212d41081------2" rel="noopener noreferrer"&gt;https://javapapers.com/core-java/java-instrumentation/116212d41081------2&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>java</category>
      <category>technology</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>How to Get Started with GoLang as a Java Developer</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Fri, 25 Feb 2022 16:46:07 +0000</pubDate>
      <link>https://dev.to/rubyshiv/how-to-get-started-with-golang-as-a-java-developer-1icd</link>
      <guid>https://dev.to/rubyshiv/how-to-get-started-with-golang-as-a-java-developer-1icd</guid>
      <description>&lt;h4&gt;
  
  
  Few simple steps to get started with GO.
&lt;/h4&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AK_t6sKmbn6k9_usmByvsKg.jpeg" 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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AK_t6sKmbn6k9_usmByvsKg.jpeg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Chinmay Bhattar on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For quite some time, I have wanted to learn GO. The programs that I used to read, appeared to be simple enough to understand.&lt;/p&gt;

&lt;p&gt;As Java developers, we are quite used to lengthy syntaxes. We don’t forget the “;” and our file name and public classes have the same name. We also take care of the visibility and access modifiers even for a simple Hello World program.&lt;/p&gt;

&lt;p&gt;I just started learning GO and find it much relatable to Java in terms of the package and import declaration and the method /function syntax. With no classes to define and semicolons to add, I find GO much quicker to develop, at least for a simple application like “Hello World”.&lt;/p&gt;

&lt;p&gt;Let’s try to implement a simple Hello World program in GO using a text editor and a Code Editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; First things first, let’s download and install Go on our local machine. Installation steps for all the different OS’s are given in the official guide at &lt;a href="https://go.dev/doc/install" rel="noopener noreferrer"&gt;https://go.dev/doc/install&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have installed the below-given version of golang, (use go version command to check that)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go version go1.17.7 darwin/amd64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, go would be installed at the below path,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usr/local/go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Create the project structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A GO project must have 3 directories — bin, pkg, and src.&lt;/p&gt;

&lt;p&gt;Under the src folder, we will create our application folders and files.&lt;/p&gt;

&lt;p&gt;bin folder stores all the binaries generated from the application and the downloaded dependencies.&lt;/p&gt;

&lt;p&gt;pkg is an intermediate folder that holds the compiled objects from src directory.&lt;/p&gt;

&lt;p&gt;A simple project structure would look like the one below,&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%2Fcdn-images-1.medium.com%2Fmax%2F731%2F1%2Ak2uNBp73zDTqGMt9187j4g.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%2Fcdn-images-1.medium.com%2Fmax%2F731%2F1%2Ak2uNBp73zDTqGMt9187j4g.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;the directory structure of hello-world repository&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create project folder under src&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All the code that’s part of our application will go under the src folder. Let’s create a folder under the src directory which will follow the naming conventions similar to the one we use in java applications — com/something/something.&lt;/p&gt;

&lt;p&gt;In this article we are just creating a single package under the src package and named it main, it could be any other name as well. Create a file with *.go extension.&lt;/p&gt;

&lt;p&gt;The first thing in a go file must be the package declaration, followed by the imports under two simple brackets “(“ and “)”. Next, write the “main()” function that would use the fmt package to call “Println” function.&lt;/p&gt;

&lt;p&gt;“main()” function must be declared in the main package else the compiler would complain.&lt;/p&gt;

&lt;p&gt;Here’s the complete code to this hello world program&lt;br&gt;
&lt;/p&gt;

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

import ("fmt")

func main(){
 fmt.Println("Hello World")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run this program, go to the program’s directory and execute the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go run Main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output to the above command would be — Hello World&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 (Optional): Use a Code Editor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’m quite used to using STS and Eclipse for Java programming so at first, I tried to install the go plugin to STS and create a Hello World program. My experience with Go on STS/ Eclipse was really bad, now it could be because I don't know how to configure a Go project correctly on that IDE but overall the experience was not good and the error messages didn’t make it easy to figure out the root cause.&lt;/p&gt;

&lt;p&gt;So I did some research on the best tools to use with Go. Turns out there are more code editors than IDE as such and the best IDE is GoLand by JetBrains, the same folks who developed IntelliJ.&lt;/p&gt;

&lt;p&gt;A few of the popular code editors are vim, govim, and VS Code.&lt;/p&gt;

&lt;p&gt;I have never tried VS Code before and always wanted to try it so I decided to try VS Code for GO programming.&lt;/p&gt;

&lt;p&gt;Firstly, I installed the go plugin for VS Code&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AFaI9w2q1orR2JI_snecgAg.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AFaI9w2q1orR2JI_snecgAg.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Go Extension for VS Code&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then wrote the same program shared in Step 3, using the Terminal tab in VS Code, executed the GO program.&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%2Fcdn-images-1.medium.com%2Fmax%2F950%2F1%2APJqKeV9c4XY3vSMqJ9KdDg.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%2Fcdn-images-1.medium.com%2Fmax%2F950%2F1%2APJqKeV9c4XY3vSMqJ9KdDg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;I like the fact that GO is a simple language, especially coming from a Java background.&lt;/p&gt;

&lt;p&gt;A hello world is not even the tip of the iceberg but it’s a start. While learning human languages we tend to compare the new language to the one we already know, it makes learning easier through comparison. I’m trying to follow the same approach to see how to program the specific actions that I usually carry out using Java in GO.&lt;/p&gt;

&lt;p&gt;Check &lt;a href="https://github.com/rubykv/go-examples/tree/master/hello-world/src/main" rel="noopener noreferrer"&gt;this&lt;/a&gt; repository for my GO experiments.&lt;/p&gt;




</description>
      <category>programming</category>
      <category>go</category>
      <category>java</category>
      <category>learning</category>
    </item>
    <item>
      <title>Exploring What’s Inside java.util.concurrent Package (Part 2)</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Thu, 24 Feb 2022 15:19:30 +0000</pubDate>
      <link>https://dev.to/rubyshiv/exploring-whats-inside-javautilconcurrent-package-part-2-4lp9</link>
      <guid>https://dev.to/rubyshiv/exploring-whats-inside-javautilconcurrent-package-part-2-4lp9</guid>
      <description>&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AXFL72tUIWmdKlvixbx5jzQ.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AXFL72tUIWmdKlvixbx5jzQ.png" alt="Interfaces in locks package"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above image shows the interfaces that are included in the &lt;strong&gt;java.util.concurrent.locks&lt;/strong&gt; package.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/rubyshiv/exploring-whats-inside-javautilconcurrent-package-part-1-3bl5"&gt;Part 1&lt;/a&gt; of this series, we explored the contents inside the java.util.concurrent package. If you haven’t already, I would recommend reading that part first.&lt;/p&gt;

&lt;p&gt;Interfaces and Classes in this package define a framework for locking and waiting for conditions that are different from the built-in synchronization and thus providing greater flexibility.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the Lock Interface and its implementation classes.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AgstrPDc_mvlMZORykBqfGA.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AgstrPDc_mvlMZORykBqfGA.png" alt="Lock Interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lock implementation provides the flexibility to attain and release locks at different scopes. For example, the synchronized method or blocks apply the lock over the complete object and the release and acquisition of a lock is performed in a block-structured way.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start 1st thread

Start 2nd thread

In sync method Thread 1

Value returned Thread 1

In other method Thread 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the above example, only after the entire block in the getValue() method is executed that the lock is released. After the lock is released by Thread 1, Thread 2 acquires it and executes the getSomething() method.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Note that the above code is just to emphasize the block-structure execution, we will never need to synchronize two get methods unless there is a put in the picture)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s rewrite the same code by using a Lock implementation.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In the example with Lock, we are acquiring a lock only when it's needed. This lock can be acquired and released in different scopes. When Thread 1 acquires the lock to getValue() method, Thread 2 can acquire the lock to getSomething() method.&lt;/p&gt;

&lt;p&gt;The output of the second program(one with Lock) is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start 1st thread

In sync method Thread 1

Start 2nd thread

In other method Thread 2

in unlock Thread 1

Value returned Thread 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Another functionality that the Lock provides is to check if a lock is available before entering the wait state by using tryLock() or one with timeout using tryLock(long, TimeUnit).&lt;/p&gt;

&lt;p&gt;Next, let’s take a look at the &lt;strong&gt;ReadWriteLock&lt;/strong&gt; Interface.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A_85EYHI6E5VIm1JPjDf36w.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A_85EYHI6E5VIm1JPjDf36w.png" alt="ReadWriteLock"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This interface provides methods two acquire read and write lock. For methods that only need read access to a shared resource a read lock can be acquired and for methods that need write access can create a write lock.&lt;/p&gt;

&lt;p&gt;In the below example, we will create two Threadsthat will call testLock() method. This method is partially locked by read lock and partially locked by write lock. We can see from the output that both Threads can simultaneously execute the code that's read locked but only one Thread enters the write lock at a time.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The output of the above program&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start 1st thread

Start 2nd thread

In read lock Thread 2

In read lock Thread 1

in read unlock Thread 2

in read unlock Thread 1

In write lock Thread 1

In write unlock Thread 1

Method Ends... Thread 1

In write lock Thread 2

In write unlock Thread 2

Method Ends... Thread 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While working on Lock implementations, we must be careful enough to unlock the acquired locks in the finally block so that even in cases of errors we will release the lock.&lt;/p&gt;

&lt;p&gt;In synchronized blocks, we do not have to worry about releasing locks.&lt;/p&gt;

&lt;p&gt;Now, let’s take a look at the &lt;strong&gt;Condition&lt;/strong&gt; Interface.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A0nNgHWA57dt9NLdwtPeZMQ.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A0nNgHWA57dt9NLdwtPeZMQ.png" alt="Condition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Condition instance is bound to a Lock, that is, to instantiate a Condition object we would need to get that instance from a Lock object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lock l = new ReentrantLock();

Condition condition = l.newCondition();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Condition objects act upon a single thread to suspend it using await() method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; condition.await() 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and resumes the activity once notified by another thread using signal() method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;condition.signal()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Class ArrayBlockingQueue makes use of Condition to block the thread when it's empty or full.&lt;/p&gt;

&lt;p&gt;Next, Let’s explore the classes and interfaces contained by the java.util.concurreny.atomic package.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ADHy3ecxWDWxv8WtmYAx43Q.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ADHy3ecxWDWxv8WtmYAx43Q.png" alt="concurrent.atomic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember, at the beginning of this article we made an instance variable Thread-safe by synchronizing the methods. We know that by synchronizing the methods we are applying lock over an instance and blocking all threads except one. If we want to avoid applying a lock on threads we can use the classes provided under the atomic package.&lt;/p&gt;

&lt;p&gt;An overhead however is that we need to check the existing value stored in the memory to the one that the Thread operating on the variable has using compareAndSet() method. If both match, the new value is updated else it's not. So we are expected to take care of the scenarios where the write operation did not succeed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;In this two-part series, we have explored the most commonly used Classes and Interfaces in the java.util.concurrent package and its sub-packages.&lt;/p&gt;

&lt;p&gt;In most of the real use cases related to web applications, one might not use the implementation of Lock and instead use the synchronized options but it’s always good to know the available options.&lt;/p&gt;




</description>
      <category>programming</category>
      <category>concurrency</category>
      <category>java</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>A Quick Look at The Programming Features Introduced between Java 1.8 and Java 17</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Thu, 24 Feb 2022 14:13:57 +0000</pubDate>
      <link>https://dev.to/rubyshiv/a-quick-look-at-the-programming-features-introduced-between-java-18-and-java-17-3nll</link>
      <guid>https://dev.to/rubyshiv/a-quick-look-at-the-programming-features-introduced-between-java-18-and-java-17-3nll</guid>
      <description>&lt;h4&gt;
  
  
  Features that make your Java code adhere to modern standards
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K4-n1tg4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AYNxa8U8UBqGMKKeFui6IxQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K4-n1tg4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AYNxa8U8UBqGMKKeFui6IxQ.jpeg" alt="Photo by Reka Illyes on Unsplash" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Java went real quick from 1.8 to 17 and this year version 18 is slated for release. In this article, we will try to cover the features that were released from the 1.8th version till the 17th.&lt;/p&gt;

&lt;p&gt;This is going to be a lengthy list, so let’s not spend too much time on setting up the stage.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please do note that the below list doesn’t cover all the features and changes that were introduced in each release but the ones that would be most helpful in typical programming cases and makes programming more interesting and easy.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Java 8
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Lambda:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Lambda expressions let us use functionality as a method argument. Let’s take a look at the code before Java 8 when we had to create an anonymous class to implement a simple interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread t = new Thread( new Runnable() {
 public  void run() {
  System.out.println("Start thread");
 }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Using lambda expressions, we can express the instance of a class in a single line&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread t1 = new Thread(() -&amp;gt; {
 System.out.println("Start 1st thread");
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;&lt;em&gt;Functional Interface:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A functional Interface is an Interface that has only one abstract method. Additionally, the Interface can have a default and a static method but only one abstract method.&lt;/p&gt;

&lt;p&gt;We have covered these features in length in a &lt;a href="https://blog.devgenius.io/the-lesser-known-java-8-features-49625a89424b"&gt;previous article&lt;/a&gt;, please refer to that article for examples.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Stream&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stream is an interface in the java.util.stream package that provides ways to perform sequential and parallel operations on collections.&lt;/p&gt;

&lt;p&gt;stream() method of Collection Interface returns back a stream of elements of the given collection which are of type Stream.&lt;/p&gt;

&lt;p&gt;The stream interface supports many operations that are needed to filter or map or find an aggregate result of the elements in a stream.&lt;/p&gt;

&lt;p&gt;In the example below, we call stream() method on a List and then pass a Predicate (Functional Interface) to the anyMatch() method that returns a boolean.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List&amp;lt;String&amp;gt; colors = new ArrayList&amp;lt;&amp;gt;(Arrays._asList_("Green","Yellow","Red"));

boolean isTrue = colors.stream().anyMatch(x -&amp;gt; x.equals("Red"));

System.out.println(isTrue);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;&lt;em&gt;Optional&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Optional creates a container object which may or may not contain a non-null value. Using Optional we can check whether a value is non-null (present) or not, we use isPresent() to validate that.&lt;/p&gt;

&lt;p&gt;In the sample code below, we use findAny() method of Stream Interface which returns back an Optional object. Based on the value of the Optional instance we can execute the corresponding logic.&lt;/p&gt;

&lt;p&gt;To perform a similar operation like below in the Java versions before 8, we would have to perform an explicit null check on the String.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List&amp;lt;String&amp;gt; colors = new ArrayList&amp;lt;&amp;gt;(Arrays._asList_("Green","Yellow","Red"));

Optional&amp;lt;String&amp;gt; color = colors.stream().filter(x -&amp;gt; x.equals("Black")).findAny();

System.out.println(color.isPresent()? color.get() : "Not Found");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;&lt;em&gt;Changes in java.util.concurrent package:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Interface CompletionStage and Class CompletableFuture and CompletionException were introduced in Java 8.&lt;/p&gt;

&lt;p&gt;CompletableFuture helps to perform asynchronous tasks that are much more flexible and enhanced than the Future object that existed before Java 8.&lt;/p&gt;

&lt;p&gt;Since we have already covered the concurrent package and Future in a previous article, we will not get into analyzing a sample code in the current article.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Method References (::)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Double colons can be used to invoke an existing method instead of using lambda expressions.&lt;/p&gt;

&lt;p&gt;Method References can be used to refer to static methods and instance methods. Let’s check an example where we refer to a static method.&lt;/p&gt;

&lt;p&gt;First, let’s implement a method invocation using a lambda expression,&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Main {

public static void main(String[] args) {
 List&amp;lt;Integer&amp;gt; locList = **new** ArrayList&amp;lt;&amp;gt;(Arrays._asList_(1,2,5,6));
 boolean isFound = locList.stream().anyMatch(l -&amp;gt; _isEqual_(l));
 System.out.println(isFound);
}

public static &amp;lt;T&amp;gt; boolean isEqual(T a) {
Predicate&amp;lt;T&amp;gt; isEqual = (x) -&amp;gt; x.equals(5);
return isEqual.test(a);
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;isEqual() is a static method in class Main so instead of using a lambda expression to invoke the method, we can simply use the method reference to get the job done.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Main {

public  static  void main(String[] args) {
 List&amp;lt;Integer&amp;gt; locList = new ArrayList&amp;lt;&amp;gt;(Arrays._asList_(1,2,5,6));
 boolean isFound = locList.stream().anyMatch(Main::_isEqual_);
 System.out.println(isFound);
}

public static &amp;lt;T&amp;gt; boolean isEqual(T a) {
 Predicate&amp;lt;T&amp;gt; isEqual = (x) -&amp;gt; x.equals(5);
 return isEqual.test(a);
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Java 9
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Stream.ofNullable&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since Java 8, we could create a stream of elements using Stream.of(Object… values), from Java 9 we can use Stream.ofNullable on a single element to create a stream or return an empty stream.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List&amp;lt;Location&amp;gt; locList = **new** ArrayList&amp;lt;&amp;gt;(Arrays._asList_(loc, loc1, loc2));
Stream._ofNullable_(locList);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;&lt;em&gt;Private Methods in Interface&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Java 8 introduced the concepts of default methods in Interface. If there is more than one default method that wants to share the same logic then that common logic can be implemented using private methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Java Modules&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Java module deserves an article of its own but let’s take a quick look at what it is. Java module is a technique by which packages and their related resources can be grouped together. A module contains a module descriptor that would specify the module name, dependent modules, packages that are available for other modules, etc.&lt;/p&gt;

&lt;p&gt;One of the end goals is to reduce the size of our application at runtime. If we are not using GUI, we need not add that module as a dependency in our application.&lt;/p&gt;
&lt;h4&gt;
  
  
  Java 10
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;local variable type inference&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From Java 10 onwards we can initialize non-null local variables and assign them to type var. The type of the variable is decided from the context.&lt;/p&gt;

&lt;p&gt;Sample usage is shown below,&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Sample {

public  static  void main(String[] args) {

var x = 10;
var y = 11;
System.out.println(x + y);

var obj = new TryVar();
System.out.println(obj.getName());

var c; //Illegal, Compiler will throw an error -&amp;gt; "Cannot use 'var' on variable without initializer"
}
}

class TryVar {
 String name;

 public String getName() {
  return "my name";
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Java 11
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;new method in Optional&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Under the Java 8 features, we learned how to use Optional to replace explicit null check using Optional.isPresent() method.&lt;/p&gt;

&lt;p&gt;Since Java 11, we can do a similar check using Optional.isEmpty() method which also returns a boolean based on it is null or non-null;&lt;/p&gt;
&lt;h4&gt;
  
  
  Java 12
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Collectors.teeing()&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;teeing() returns a Collector that is a composite of two downstream collectors.&lt;/p&gt;

&lt;p&gt;Let’s check an example. In this example, we will use a class named Location which has two variables x and y. In the teeing example, we will fetch the number of records that have the accepted value for x and the accepted value for y. (Logic wouldn’t make any sense but let’s just focus on how teeing works 😝 )&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Create three instances of Location
Location loc = new Location(2.2, 3.6);
Location loc1 = new Location(2.4, 3.3);
Location loc2 = new Location(2.3, 3.2);

// Add the reference variables to an ArrayList
List&amp;lt;Location&amp;gt; locList = **new** ArrayList&amp;lt;&amp;gt;(Arrays._asList_(loc, loc1, loc2));

//Count records that has correct x, Count the records that has correct y and create a new Location object  
var result = locList.stream().collect(Collectors._teeing_(Collectors._filtering_(Location :: isXFound, Collectors._counting_()),Collectors._filtering_(Location :: isYFound, Collectors._counting_()), Location :: new ));

//Print the Result
System.out.println("Records with correct X coordinate " + result.getX() + " :: Records with correct Y coordinate " + result.getY());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Class Location looks like below,&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h4&gt;
  
  
  Java 13
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Text Blocks&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Text Blocks minimize the Java syntax that is needed to represent a multi-line string.&lt;/p&gt;

&lt;p&gt;It could be used in place of any string that is conventionally added within double-quotes.&lt;/p&gt;

&lt;p&gt;Before Text Blocks, if we had to print a multi-line string, we would need to use delimiters, concatenations, etc.&lt;/p&gt;

&lt;p&gt;For example, the below code would give us the complete string in a single line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System.out.print("Hey There "

+ "What's up?? "

+ "How was your vacation?? "

+ ";)");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hey There What's up?? How was your vacation?? ;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To print them in the next line we will have to modify the above code to the one given below,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System.out.print("Hey There \n"

+ "What's up?? \n"

+ "How was your vacation?? \n"

+ ";)");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using Text Blocks we can rewrite the above code to the one given below,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System.out.print("""

Hey There

What's up??

How was your vacation??

;)

""");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Text Blocks can also be used in place of standard strings.&lt;/p&gt;

&lt;p&gt;For example, both strings shown below have the same meaning&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_//Text Block  
printMsg_ ("""
Print This!! """);

// String in Double Quotes
_printMsg_("Print this!");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Java 14
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Records&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Records is a restricted form of class that is ideal for POJOs. A standard data-carrier-class would have a few private fields along with constructors and getters/setters.&lt;/p&gt;

&lt;p&gt;Let’s check an example of a simple data-carrier class that has two members,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public  class Location {
double x;
double y;

public Location(double x, double y) {
this.x = x;
this.y = y;
}

public double getX() {
 return x;
}

public double getY() {
 return y;
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can rewrite the above class using a Record using the below-given code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;record NewLocation( **double** x, **double** y) {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Record will acquire the getters and constructors at runtime. It also gets the equals(), hashcode() and toString() methods.&lt;/p&gt;

&lt;h4&gt;
  
  
  Java 15
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Sealed Class / Interface&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;sealed is a modifier we can add to a Class and Interface. A sealed class can decide the subclasses that can extend it and stop other classes from doing so.&lt;/p&gt;

&lt;p&gt;To declare a Class / Interface as sealed, we need to add the “sealed” modifier and then add extends or implements, if applicable, followed by “permits” clause. “permits” is followed by the name of the subclasses that are allowed to extend it.&lt;/p&gt;

&lt;p&gt;Other conditions are that, the subclass that’s extending a sealed class can be 1. final — which stops it from further extensions,  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;sealed — which lets the sealed subclass define it’s own permitted subclasses,
&lt;/li&gt;
&lt;li&gt;non-sealed — let’s any arbtrary class extend it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, if Location is a sealed class, then we can declare it as,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public  sealed  class Location permits SubLocation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the Sublocation class could be declared as,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public  final  class SubLocation extends Location{}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public  sealed  class SubLocation extends Location permits AnotherClass{}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public non-sealed class SubLocation extends Location{}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Java 16
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Stream.toList()&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From Java 16, we can collect the result from stream directly to a list instead of using Collectors.toList().&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List&amp;lt;Integer&amp;gt; collectedList = locList.stream().filter( l -&amp;gt; l &amp;gt;=2).collect(Collectors._toList_());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code will yield the same result as the one given below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List&amp;lt;Integer&amp;gt; collectedListNew = locList.stream().filter( l -&amp;gt; l &amp;gt;=2).toList();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Java 17
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Pattern matching for switch&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of just using constant values in switch cases we can now use patterns as case labels.&lt;/p&gt;




</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>java</category>
      <category>java17</category>
    </item>
    <item>
      <title>Exploring What’s Inside java.util.concurrent Package (Part 1)</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Sun, 20 Feb 2022 15:23:54 +0000</pubDate>
      <link>https://dev.to/rubyshiv/exploring-whats-inside-javautilconcurrent-package-part-1-3bl5</link>
      <guid>https://dev.to/rubyshiv/exploring-whats-inside-javautilconcurrent-package-part-1-3bl5</guid>
      <description>&lt;h4&gt;
  
  
  Just the stuff you need for your day-to-day programming tasks
&lt;/h4&gt;

&lt;p&gt;java.util.concurrent package in Java contains Interfaces and Classes that make concurrent programming possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Concurrent Programming?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zWWtVS8X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AKYq71QUFSDr0Mb3OJ1GoqQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zWWtVS8X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AKYq71QUFSDr0Mb3OJ1GoqQ.png" alt="" width="880" height="495"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Concurrency&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In a program, when more than one process appears to be running at the same time we have concurrency. Why appear and not in real? If two processes are actually running at the same time we have parallelism.&lt;/p&gt;

&lt;p&gt;We are not getting much into the concept of concurrency but rather exploring the content inside the java package that makes concurrency possible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;NB: It will not be possible to cover all that’s mentioned in the content segment in a single article, so I will cover them all in multiple parts (hopefully two would be enough).&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Content
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;java.util.concurrent
a) Executors &amp;amp; Future
b) Concurrent Collections&lt;/li&gt;
&lt;li&gt;java.util.concurrent.locks&lt;/li&gt;
&lt;li&gt;java.util.concurrent.atomic&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  java.util.concurrent
&lt;/h4&gt;

&lt;p&gt;The main components contained in this package are — Executors, Queues, Timing, Synchronizers, and Concurrent Collections.&lt;/p&gt;

&lt;p&gt;In this article, we will explore the two components that are heavily used in web-based applications — Executors and Concurrent Collections.&lt;/p&gt;

&lt;p&gt;The classes and interfaces along with their hierarchy in the executor framework are shown in the below image,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Executors&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lOF6Il4x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A-JIEnqLxsza5HuZAm4Ebdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lOF6Il4x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A-JIEnqLxsza5HuZAm4Ebdg.png" alt="" width="880" height="495"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Interface and Class Hierarchy in the java.util.concurrent package&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The difference between ThreadPoolExecutor and ScheduledThreadPoolExecutor classes is that the latter can be used to schedule task executions, like add a delay, etc.&lt;/p&gt;

&lt;p&gt;Another important class one needs to remember in this package is Executors. This class provides factory methods for most of the configurations that one would need while working on executors.&lt;/p&gt;

&lt;p&gt;We can either use these given classes or implement the interface and provide our own implementation.&lt;/p&gt;

&lt;p&gt;Let’s try to use the interfaces and create a ThreadPool and execute a few tasks by fetching threads from that pool. We will use the methods from the &lt;strong&gt;Executors&lt;/strong&gt; factory class to create thread pool.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the above sample, we created a ThreadPool with the initial size of 2. We also provided our own implementation of ThreadFactory which is optional. We can skip our own implementation and the executor will take the default ThreadFactory implementation. The reason we are implementing our own factory is to give a name to the new Thread and identify which thread is running our tasks.&lt;/p&gt;

&lt;p&gt;Next, we executed three tasks using the submit() methods of ExecutorService. Note that, all three of them have a different signature. We can submit the tasks using tasks of type Callable or Runnable.&lt;/p&gt;

&lt;p&gt;The output of the above code is::&lt;br&gt;
&lt;/p&gt;

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

Implemented Runnable Interface2

Implemented Callable Interface2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The first task was run by Thread 1 and the next two were run by Thread 2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Future, Runnable, and Callable&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Runnable and Callable perform a similar job. They both execute a task in a new thread but &lt;a href="https://www.java67.com/2013/01/difference-between-callable-and-runnable-java.html"&gt;Callable can return a result&lt;/a&gt; and also can throw a checked exception.&lt;/p&gt;

&lt;p&gt;Future is an interface with a signature Interface Future. It represents the result of asynchronous execution. In the above code sample, submit methods of executor returns back a Future.&lt;/p&gt;

&lt;p&gt;Many classes in the concurrent package implement this interface, let’s take a look at one of the most commonly used implementations of Future Interface — CompletableFuture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CompletableFuture&lt;/strong&gt; has the following signature,&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class CompletableFuture&amp;lt;T&amp;gt;
extends Object
implements Future&amp;lt;T&amp;gt;, CompletionStage&amp;lt;T&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let’s check some of the methods that belong to this class.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;runAsync() : Returns a new CompletableFuture. Takes a Runnable object. If you want to run a code block and do not expect a return value then use this method.&lt;/li&gt;
&lt;li&gt;supplyAsync() : Returns a new CompletableFuture.Takes a Supplier object and also returns the value that was obtained by calling the given Supplier . If you want to run a code block and expect a return value then use this method.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that, both of these methods have an option to accept an executor instance as a parameter. If we do not supply an executor to the these methods then new Threads are created using ForkJoinPool.commonPool().&lt;/p&gt;

&lt;p&gt;We have already implemented our own ThreadPool and have control over the number of threads that would be created by default so I prefer to pass an instance of executor as a param.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;thenAccept() : Get the result of a CompletedFuture task and pass it as an argument to a Consumer object. If you need to run a task based on the result of a Future object and do not want a result back from that task then use this method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;thenApply() : Get the result of a CompletedFuture task and pass it as an argument to a Function object. If you need to run a task based on the result of a Future object and need a result back from that task then use this method.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;thenCompose() : If you want to combine the result of two future executions where one future task depends on another future task’s output then use this method.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;thenCombine(): If you want to combine the output of two independent future tasks then use this method.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Modify the above code to make the following changes and we will yield the same result as the above code.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;&lt;em&gt;Concurrent Collections&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Collection implementations that are designed for multi-threaded contexts are&lt;/p&gt;

&lt;p&gt;ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet, CopyOnWriteArrayList, and CopyOnWriteArraySet&lt;/p&gt;

&lt;p&gt;Note that the behavior of these classes is different from the synchronized classes.&lt;/p&gt;

&lt;p&gt;For example, Collections.synchronizedList(new ArrayList()); returns a synchronized ArrayList. Thread safety on a synchronized collection is achieved by applying a Thread lock on the entire object.&lt;/p&gt;

&lt;p&gt;CopyOnWriteArrayList, the concurrent alternative to the synchronized list achieves Thread safety by allowing multiple threads to read from the collection without applying a lock on the instance and the lock is applied only for the update.&lt;/p&gt;

&lt;p&gt;concurrent collections are preferred over the Synchronized collection for better performance and scalability.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:: We will explore the other two sub packages in the next article.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>programming</category>
      <category>concurrency</category>
      <category>java</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Deploy SpringBoot App to Elastic Beanstalk Using Github Actions CI/CD</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Thu, 17 Feb 2022 15:58:16 +0000</pubDate>
      <link>https://dev.to/rubyshiv/how-to-deploy-springboot-app-to-elastic-beanstalk-using-github-actions-cicd-2ihi</link>
      <guid>https://dev.to/rubyshiv/how-to-deploy-springboot-app-to-elastic-beanstalk-using-github-actions-cicd-2ihi</guid>
      <description>&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A9otOB3D3OcD52DzRMWQsiA.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A9otOB3D3OcD52DzRMWQsiA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above image gives an overview of this article.&lt;/p&gt;

&lt;p&gt;We will build a spring-boot application using Java and Maven and deploy it to AWS Elastic Beanstalk. Instead of manually deploying our application to AWS we will create a CI/CD pipeline using GitHub Actions for deployment.&lt;/p&gt;

&lt;p&gt;If you followed my previous articles, you would have read about the &lt;a href="https://medium.com/javarevisited/a-complete-guide-to-build-and-deploy-a-saas-product-from-scratch-669042348dd8" rel="noopener noreferrer"&gt;SaaS application&lt;/a&gt; that was deployed to an EC2 instance, we are going to reuse the same code in this article but you can choose to use any spring-boot application to try the steps given here.&lt;/p&gt;

&lt;p&gt;Before getting into the implementation, let’s try to refresh our memory on how &lt;a href="https://dev.to/rubyshiv/continuous-deployment-and-workflow-automation-using-github-actions-4gk5"&gt;Github Actions&lt;/a&gt; work. (we will not cover how GitHub Actions work in this article)&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementation
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 1: Create or download a Spring-Boot application.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We know that the default port where tomcat runs is 8080 and that’s where we access our spring-boot application as well. As we start using a registry or have more than one spring-boot app running in our local, we define the server port explicitly in the application property or yml file. Something similar needs to be done while deploying a code to AWS beanstalk. AWS has Nginx running at port 80 and that internally points to port 5000 by default. So, in our application, we would explicitly mention the server port as 5000.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 2: Create a new application on Elastic Beanstalk&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create an AWS account if you haven’t already and I would also recommend you to create an IAM user for this purpose, instead of using the Admin user.&lt;/p&gt;

&lt;p&gt;Once the account is created, let’s create a new application with the following configurations,&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A2LEEgByZG2ofUZBQ_rbNQQ.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A2LEEgByZG2ofUZBQ_rbNQQ.png"&gt;&lt;/a&gt;&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A_4NVPHyrLnMmd8Xcy72hrg.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A_4NVPHyrLnMmd8Xcy72hrg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the “Create Application” button.&lt;/p&gt;

&lt;p&gt;It takes a couple of minutes to configure the application before it becomes available for use.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AzqldMchZudUl7zvGYh7YxA.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AzqldMchZudUl7zvGYh7YxA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once done, we would be greeted with the below page.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Af35nFgaKDyYVy38zkbi5NA.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Af35nFgaKDyYVy38zkbi5NA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our sample application is up in AWS, we can copy the endpoint of this page as our application will be accessed using that endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 3: Implement CI/CD&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In our previous article on &lt;a href="https://dev.to/rubyshiv/continuous-deployment-and-workflow-automation-using-github-actions-4gk5"&gt;Github Actions&lt;/a&gt;, we learned the basic concepts and what each keyword means. Let’s now use a few of them.&lt;/p&gt;

&lt;p&gt;In the GitHub repository, let’s create a yml file under “.github/workflows” folder. We have named our yml file — deploy.yml but you can choose any other suitable name.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We have defined two jobs here, one is to build and another is to deploy the jar.&lt;/p&gt;

&lt;p&gt;Make sure you replace the path in build to your “target/.jar and also rename the deployment_package field accordingly.&lt;/p&gt;

&lt;p&gt;application_name and environment_name under deploy event should match with the name you provided to your beanstalk application and environment.&lt;/p&gt;

&lt;p&gt;AWS access key and secret can be obtained from the AWS portal under Your profile -&amp;gt; Security credentials -&amp;gt;Access keys for CLI, SDK, &amp;amp; API access -&amp;gt; Create access key.&lt;/p&gt;

&lt;p&gt;Store these values in your GitHub repository under settings -&amp;gt; Secrets.&lt;/p&gt;

&lt;p&gt;Once the changes are made, commit the file. This would trigger the workflow and you can check the status under the actions tab.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AeGtMSmG04wKOP4UBMZdt7w.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AeGtMSmG04wKOP4UBMZdt7w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if you are using the “autocluck” code repository then you will need to set up MongoDB in an EC2 instance but if you are using a simple application that has no DB dependency then skip the next step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 4: Set up Mongo DB in EC2 (Optional)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For those of us using the “autocluck” repository, we would need to create a new instance in EC2 and install Mongo DB in it. Follow the steps mentioned in &lt;a href="https://medium.com/javarevisited/a-complete-guide-to-build-and-deploy-a-saas-product-from-scratch-669042348dd8" rel="noopener noreferrer"&gt;my previous article&lt;/a&gt; to complete the setup.&lt;/p&gt;

&lt;p&gt;Once done, check the public IP of that EC2 instance and update the connection string in “DatabaseConfig” java class in our application with that address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final ConnectionString connectionString = new ConnectionString("mongodb://xx.xxx.xx.xxx:27017/test");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 5: Test the application&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s test the application by hitting the health check API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --location --request GET '&amp;lt;beanstalk -endpoint&amp;gt;:80/api/tweet/health' \

--header 'Content-Type: application/json' \

--data-raw '{}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response&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%2Fcdn-images-1.medium.com%2Fmax%2F615%2F1%2Aars-flgfUPcZcA8XaHqiHg.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%2Fcdn-images-1.medium.com%2Fmax%2F615%2F1%2Aars-flgfUPcZcA8XaHqiHg.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;200 OK&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;We just automated the deployment process of our spring boot application. With Github actions, we can now add more workflows to run the tests so we make sure broken code is not deployed to production and also add code coverage tools to maintain code standards. It’s also easy to collaborate with multiple users and take the product to market quickly.&lt;/p&gt;




</description>
      <category>java</category>
      <category>aws</category>
      <category>springboot</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>My Data on AWS got Hacked!</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Sun, 13 Feb 2022 16:06:33 +0000</pubDate>
      <link>https://dev.to/rubyshiv/my-data-on-aws-got-hacked-570p</link>
      <guid>https://dev.to/rubyshiv/my-data-on-aws-got-hacked-570p</guid>
      <description>&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A-OrmuqUusMkhEGgaUozXDQ.jpeg" 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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A-OrmuqUusMkhEGgaUozXDQ.jpeg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by sebastiaan stam on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Life is unpredictable they say, for software developers there can't be a more true statement. We don’t know what awaits us each day when we open our laptops.&lt;/p&gt;

&lt;p&gt;Today was such a day in my life.&lt;/p&gt;

&lt;p&gt;If you have been reading my articles, you would know that I was building a &lt;a href="https://medium.com/javarevisited/a-complete-guide-to-build-and-deploy-a-saas-product-from-scratch-669042348dd8" rel="noopener noreferrer"&gt;tweet scheduler&lt;/a&gt; for fun and learning. Nothing serious, just wanted to figure out how deployment to AWS works and what are the basic steps to be followed to develop and deploy a product from scratch.&lt;/p&gt;

&lt;p&gt;Every day I had a new challenge to face and I was learning about AWS faster than I could have by enrolling in a course. So far so good.&lt;/p&gt;

&lt;p&gt;Yesterday I found two issues with the app. One was that the app deployed on elastic beanstalk had its health status shown in RED. The issue was labeled as “Severe” with the following warning message,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ELB health is failing or not available for all instances&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was not sure how to troubleshoot the issue and I was also getting a proper response from the health check API of the application.&lt;/p&gt;

&lt;p&gt;As the app was deployed just for demo purposes, I had only one EC2 instance up for this without a load balancer. So the problem turned out to be that, health check on AWS is by default performed on “/” path. That is, an application would need to create an API that can be accessed at the root path and responds with a 200 OK. If we need a custom health check API to be invoked instead of a default one then that needs to be configured.&lt;/p&gt;

&lt;p&gt;So I created a new API that responds with a 200 OK.&lt;/p&gt;

&lt;p&gt;Committed the code and the deployment started using the CI/CD pipeline and deployment FAILED.&lt;/p&gt;

&lt;p&gt;Turns out my MongoDB didn't have any of the collections that are needed for my application to start. I wondered how that happened and didn't give it a second thought. I already had the data backup so I just created those collections again in the MongoDB that’s deployed on another EC2 instance.&lt;/p&gt;

&lt;p&gt;All good again, the app is up and tweets again.&lt;/p&gt;

&lt;p&gt;The same thing happened the next day as well, I couldn’t find the collections in my Mongo DB, my first hunch was something is autodeleting the collections if not in use (Developer’s wild thoughts). This time though I really wanted to understand the issue.&lt;/p&gt;

&lt;p&gt;After googling the issue for a while, I got a hint that an exposed DB(one without access restrictions) has security concerns and is vulnerable to attack. I didn’t have any sensitive data stored in DB, just a few links to my articles and a few tokens created for the app for testing purposes, and that made me a little insensitive towards the security aspect of an application and data that can be accessed from any IP address.&lt;/p&gt;

&lt;p&gt;As any developer, I started with the logs to find the clue. Went through the mongo logs and found this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"t":{"$date":"2022-02-09T01:59:59.878+00:00"},"s":"I", "c":"STORAGE", "id":22206, "ctx":"conn86","msg":"Deferring table drop for index","attr":{"index":"_id_","namespace":"config.system.sessions","uuid":{"uuid":{"$uuid":"a6892f16-e340-4197-9a94-a5d8b247e1ad"}},"ident":"index-5-2402867815965632471","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}

{"t":{"$date":"2022-02-09T01:59:59.878+00:00"},"s":"I", "c":"STORAGE", "id":22206, "ctx":"conn86","msg":"Deferring table drop for index","attr":{"index":"lsidTTLIndex","namespace":"config.system.sessions","uuid":{"uuid":{"$uuid":"a6892f16-e340-4197-9a94-a5d8b247e1ad"}},"ident":"index-6-2402867815965632471","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}

{"t":{"$date":"2022-02-09T01:59:59.878+00:00"},"s":"I", "c":"STORAGE", "id":22214, "ctx":"conn86","msg":"Deferring table drop for collection","attr":{"namespace":"config.system.sessions","ident":"collection-4-2402867815965632471","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}

{"t":{"$date":"2022-02-09T01:59:59.878+00:00"},"s":"I", "c":"COMMAND", "id":20336, "ctx":"conn86","msg":"dropDatabase","attr":{"db":"config","numCollectionsDropped":1}}

{"t":{"$date":"2022-02-09T01:59:59.886+00:00"},"s":"I", "c":"COMMAND", "id":20337, "ctx":"conn86","msg":"dropDatabase - starting","attr":{"db":"local"}}

{"t":{"$date":"2022-02-09T01:59:59.886+00:00"},"s":"I", "c":"COMMAND", "id":20338, "ctx":"conn86","msg":"dropDatabase - dropping collection","attr":{"db":"local","namespace":"local.startup_log"}}

{"t":{"$date":"2022-02-09T01:59:59.886+00:00"},"s":"I", "c":"STORAGE", "id":22206, "ctx":"conn86","msg":"Deferring table drop for index","attr":{"index":"_id_","namespace":"local.startup_log","uuid":{"uuid":{"$uuid":"3a353cc7-7fd3-44cc-8959-24aa8b02de8c"}},"ident":"index-3-2402867815965632471","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}

{"t":{"$date":"2022-02-09T01:59:59.886+00:00"},"s":"I", "c":"STORAGE", "id":22214, "ctx":"conn86","msg":"Deferring table drop for collection","attr":{"namespace":"local.startup_log","ident":"collection-2-2402867815965632471","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}

{"t":{"$date":"2022-02-09T01:59:59.886+00:00"},"s":"I", "c":"COMMAND", "id":20336, "ctx":"conn86","msg":"dropDatabase","attr":{"db":"local","numCollectionsDropped":1}}

{"t":{"$date":"2022-02-09T01:59:59.893+00:00"},"s":"I", "c":"COMMAND", "id":20337, "ctx":"conn86","msg":"dropDatabase - starting","attr":{"db":"test"}}

{"t":{"$date":"2022-02-09T01:59:59.893+00:00"},"s":"I", "c":"COMMAND", "id":20338, "ctx":"conn86","msg":"dropDatabase - dropping collection","attr":{"db":"test","namespace":"test.identity"}}

{"t":{"$date":"2022-02-09T01:59:59.893+00:00"},"s":"I", "c":"COMMAND", "id":20338, "ctx":"conn86","msg":"dropDatabase - dropping collection","attr":{"db":"test","namespace":"test.cred"}}

{"t":{"$date":"2022-02-09T01:59:59.893+00:00"},"s":"I", "c":"COMMAND", "id":20338, "ctx":"conn86","msg":"dropDatabase - dropping collection","attr":{"db":"test","namespace":"test.tweet"}}

{"t":{"$date":"2022-02-09T01:59:59.901+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn86","msg":"createCollection","attr":{"namespace":"READ__ME_TO_RECOVER_YOUR_DATA.README","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"9c5b4513-66b6-499d-924b-3ecf1a9d9140"}},"options":{}}}

{"t":{"$date":"2022-02-09T01:59:59.912+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn86","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"READ__ME_TO_RECOVER_YOUR_DATA.README","index":"_id_","commitTimestamp":null}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, clearly someone out there had been dropping my collections!&lt;/p&gt;

&lt;p&gt;Towards the end of the logs, I found that the hacker was creating a new collection and the name said it all “READ__ME_TO_RECOVER_YOUR_DATA”.&lt;/p&gt;

&lt;p&gt;Clearly, the script that hacked my database had no idea if the app was a real-world application or a dummy one.&lt;/p&gt;

&lt;p&gt;Just out of curiosity, I read the message that was left on the newly created collection. The collection had one document in it and this was the content,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"_id":{"$oid":"62049c7cc4b8ad66550b7383"},"content":"All your data is a backed up. You must pay 0.021 BTC to 17jHiu7FGUX8xcotaxBnxnNZRTqU86kr8b 48 hours for recover it. After 48 hours expiration we will leaked and exposed all your data. In case of refusal to pay, we will contact the General Data Protection Regulation, GDPR and notify them that you store user data in an open form and is not safe. Under the rules of the law, you face a heavy fine or arrest and your base dump will be dropped from our server! You can buy bitcoin here, does not take much time to buy https://localbitcoins.com or https://buy.moonpay.io/ After paying write to me in the mail with your DB IP: recmydb+17o8d@onionmail.org and you will receive a link to download your database dump."}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hacker wants 0.021 BTC in exchange for my data, in USD that’s close to 958$ as of Feb 10th, 2022.&lt;/p&gt;

&lt;p&gt;To those, who like me, haven’t heard of onionmail before, one can create an emailId that would be private and anonymous at onionmail.org. (Sounds like hackers' favorite space).&lt;/p&gt;

&lt;p&gt;So I have stopped the EC2 instance, regenerated the tokens, and stopped my application as well. I will bring it up as and when I’m trying something new on it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lessons Learnt
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Any instance of the app that’s deployed for demo needs to be shut down right after the demo purposes.&lt;/li&gt;
&lt;li&gt;Basic security must be taken care of even for fun projects.&lt;/li&gt;
&lt;li&gt;With more apps being built using blockchain technology, cyber-security has become an extremely crucial aspect of any application.&lt;/li&gt;
&lt;/ol&gt;




</description>
      <category>aws</category>
      <category>mongodb</category>
      <category>cybersecurity</category>
      <category>cybercrime</category>
    </item>
    <item>
      <title>Continuous Deployment and Workflow Automation using Github Actions</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Wed, 09 Feb 2022 14:53:12 +0000</pubDate>
      <link>https://dev.to/rubyshiv/continuous-deployment-and-workflow-automation-using-github-actions-4gk5</link>
      <guid>https://dev.to/rubyshiv/continuous-deployment-and-workflow-automation-using-github-actions-4gk5</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tJhTUOgZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AeD_KPH0EGOhJqxgz6wQ_Hw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tJhTUOgZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AeD_KPH0EGOhJqxgz6wQ_Hw.png" alt="" width="880" height="495"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Github Actions&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Github Actions makes it easy for developers to automate software workflows.&lt;/p&gt;

&lt;p&gt;Before Github Actions, we had to use a CI/CD tool like Jenkins to trigger a build every time code is pushed to the repository. We also use to integrate these builds with plugins for code quality checks like Sonar.&lt;/p&gt;

&lt;p&gt;These activities are usually performed by a designated DevOps team. On the other hand, consider an open-source project, one that runs purely from the support of contributors, how would you make sure the code quality is not degraded with too many people contributing to a project or that functionality is not broken by a new fix?&lt;/p&gt;

&lt;p&gt;Github Actions helps us fix that issue. We can take actions based on the events that take place at the repository like push, PR, etc.&lt;/p&gt;

&lt;p&gt;Let’s see how to configure a workflow in our project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dLC6knaB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ApoVqhn3nbvTSeNlajRO8yw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dLC6knaB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ApoVqhn3nbvTSeNlajRO8yw.jpeg" alt="" width="880" height="574"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Roman Synkevych on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The end goal of each workflow depends on the use case but the most commonly used workflow is CI/CD. You can also define more than one workflow, one for deployment, one to send out a greeting message, and so on.&lt;/p&gt;

&lt;p&gt;Each workflow is written in its own file and follows yml syntax. File extension could be yml or yaml and the name of the file could be anything that the developer decides.&lt;/p&gt;

&lt;p&gt;All the workflow yml files must be placed under the “.github/workflows” directory of your repository.&lt;/p&gt;
&lt;h4&gt;
  
  
  Workflow File Items
&lt;/h4&gt;

&lt;p&gt;Let’s start with the most basic items that are part of the workflow files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Deployment
on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;name:&lt;/em&gt;&lt;/strong&gt; This field names the workflow, which will show up under the GitHub actions tab once the workflow runs. (Check below image)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GT0ki08n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AbCFT80Odwipl-9V7WbR4Bw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GT0ki08n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AbCFT80Odwipl-9V7WbR4Bw.png" alt="" width="880" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;on:&lt;/em&gt;&lt;/strong&gt; Under this field, we define the events that should trigger the workflow to run.&lt;/p&gt;

&lt;p&gt;In the above sample file, we have defined two events, push and pull_request, that would trigger the workflow to run.&lt;/p&gt;

&lt;p&gt;If we want the deployment workflow to trigger only when source code is modified then we can explicitly mention that like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on:
  push:
    branches:    
      - main
    paths:
      - '**.java'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By explicitly providing the paths as'**.java' in our yml file, we can make sure that only when “.java” file under the “main” branch is committed, our workflow will run.&lt;/p&gt;

&lt;p&gt;Yet another way of defining the directories that need to be avoided and included is given below. “!” indicates we wish to avoid the path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on:
  push:
    paths:
      - 'sub-project/**'
      - '!sub-project/docs/**'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above configuration, the workflow will run if the commit file is under “sub-project" directory but it will not run if the file is under “sub-project/docs" directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK
        uses: actions/setup-java@v1
        with:
          java-version: '8'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another item that usually follows “on” is “jobs”.&lt;/p&gt;

&lt;p&gt;Events defined under the “on” key will trigger the items defined under the “jobs” key.&lt;/p&gt;

&lt;p&gt;One or more jobs would be usually listed in a workflow with each having its own unique job id. In the above sample yml file “build” is the job id.&lt;/p&gt;

&lt;p&gt;Next, we define the name of this particular job, which will show up under the GitHub Actions tab when the workflow runs, as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hLFLMir2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AiCAziMejcBLFMQxRlI0LmQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hLFLMir2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AiCAziMejcBLFMQxRlI0LmQ.png" alt="" width="880" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;runs-on:&lt;/em&gt;&lt;/strong&gt; Each job runs in a virtual server called runner environment. We can choose the environment we want to run these jobs on from macOS, Ubuntu, and Window Servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;steps:&lt;/em&gt;&lt;/strong&gt; This is a sequence of tasks under a job. This could run actions that are available in public repositories( so we do not have to write them again), or set up tasks like running an application build.&lt;/p&gt;

&lt;p&gt;If we are using an existing action as one of the steps we can declare that using “uses” keyword, if we are defining the command then that can be declared using “run” keyword. Check the sample file below.&lt;/p&gt;

&lt;p&gt;We can search for pre-defined actions at github.com/actions repository and use them as needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build:
  name: Build
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v1
    - name: Set up JDK
      uses: actions/setup-java@v1
      with:
        java-version: '8'
    - name: Build with Maven
      run: mvn -B package -DskipTests --file pom.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each job runs in a virtual server and is run parallelly by default. If one job has a dependency on another one like deployment and build, then we will have to execute them sequentially. This is achieved by declaring a job dependency using the “needs” keyword.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deploy:
  needs: build
  name: Deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer to the official documentation of GitHub Actions to learn about all the features that could be included in a workflow and to find the right keyword used in different use cases.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Github Actions has given a big boost to the open-source software community and to developers working on various side projects to automate the many flows without any additional configuration and downloads.&lt;/p&gt;

&lt;p&gt;Even the &lt;a href="https://medium.com/javarevisited/a-complete-guide-to-build-and-deploy-a-saas-product-from-scratch-669042348dd8"&gt;autocluck project&lt;/a&gt; that I was working on to schedule my tweets is using Github Actions now to deploy the app to AWS. If you would like to check the workflow file for that project for reference, it's available on &lt;a href="https://github.com/rubykv/autocluck/blob/main/.github/workflows/deploy.yml"&gt;Github&lt;/a&gt;.&lt;/p&gt;




</description>
      <category>tutorial</category>
      <category>github</category>
      <category>devops</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Implementing Spring Kafka in a Simple SpringBoot Application</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Sat, 05 Feb 2022 15:04:03 +0000</pubDate>
      <link>https://dev.to/rubyshiv/implementing-spring-kafka-in-a-simple-springboot-application-1afp</link>
      <guid>https://dev.to/rubyshiv/implementing-spring-kafka-in-a-simple-springboot-application-1afp</guid>
      <description>&lt;p&gt;Apache Kafka is an event streaming platform where data flows from one system to another. Its use cases are but are not limited to, IoT, real-time data analytics, log aggregation and analysis, message broker, and so on.&lt;/p&gt;

&lt;p&gt;In this article, we will learn how apache Kafka is used as a message broker. The role of a message broker is to pass data from one system or service to another system or service.&lt;/p&gt;

&lt;p&gt;As microservices became popular in the software industry, Kafka became a useful tool to make asynchronous communication possible.&lt;/p&gt;

&lt;p&gt;How Kafka works as a message broker is shown in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javarevisited.blogspot.com/2018/04/top-5-apache-kafka-course-to-learn.html"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B01PrIB9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ADkDhfJKHoBk8sZMCn7SuWQ.png" alt="" width="880" height="495"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Simple representation of Apache Kafka as Message Broker&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Spring Kafka is Spring’s implementation of adding an abstraction over Kafka java client. It comes with a template and message-driven POJOs, we will learn more about that in the implementation section.&lt;/p&gt;

&lt;p&gt;To implement Spring Kafka, we would first need to set up Kafka in our local machine.&lt;/p&gt;
&lt;h4&gt;
  
  
  Few terms to remember
&lt;/h4&gt;

&lt;p&gt;Producer-Consumer: Producer is the application that would write data to the Kafka topics and Consumer is the application that would read the data.&lt;/p&gt;

&lt;p&gt;Events: Data read or written to Kafka is in the form of events. These are like files stored in the file system with basically three pieces of information — key, value, and timestamp. (we will see more on key and value in the implementation segment)&lt;/p&gt;

&lt;p&gt;Topic: Events are organized as topics. A producer writes to a topic and consumer reads from a topic.&lt;/p&gt;

&lt;p&gt;Partition: Topics are partitioned. Think of partitions like files and they are stored within a topic which we can think of like folders.&lt;/p&gt;

&lt;p&gt;Segments: Segment is a collection of all the messages that are written to a topic. Each partition is actually stored in a sequence of segments that is instead of a single file, data is split into multiple segments.&lt;/p&gt;

&lt;p&gt;Zookeeper: Zookeeper is not a part of apache Kafka but is required to maintain Kafka topics and messages in a distributed environment. We will have to run Zookeeper before we run Kafka.&lt;/p&gt;
&lt;h4&gt;
  
  
  Kafka Installation
&lt;/h4&gt;

&lt;p&gt;Refer to the steps mentioned in &lt;a href="https://kafka.apache.org/quickstart"&gt;https://kafka.apache.org/quickstart&lt;/a&gt;, the official Kafka website for the installation process.&lt;/p&gt;

&lt;p&gt;Once the installation is complete, you will be able to send and receive messages as shown below. At this point, we have ensured that the installation is working fine.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please note that, for this tutorial to work we just need to follow steps 1 and 2 from the installation steps mentioned on the Kafka website. That is, download the Kafka zip file and extract it to your local, start zookeeper and Kafka servers. We do not need to manually create the topic or start the consumer or producer, that part we will do from our application. you can terminate the producer and consumer in your terminal using Ctrl+C if you have already started them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rjKHLRzq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AY8gy-bry8sKHaJwyfpG2fQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rjKHLRzq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AY8gy-bry8sKHaJwyfpG2fQ.png" alt="" width="880" height="521"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;messages are published and received&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Implement Spring Kafka with Spring Boot
&lt;/h4&gt;

&lt;p&gt;Now, let’s create a spring boot application from the spring initilzr web application. Make sure to add web and Kafka dependency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javarevisited.blogspot.com/2020/05/top-20-spring-boot-interview-questions-answers.html"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6ElQ_h8q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ABldfVoQIUDlazsroL_ToKQ.png" alt="" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will start with configuring KafkaTemplate for the producer and also explicitly implement the deserialization technique for the consumer.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here, the key is automatically assigned by Kafka and value is the record that we publish to a Kafka topic. If both key and value are String then we can provide StringDeserializer instead of a JsonDeserializer (Check the complete code in Github for more).&lt;/p&gt;

&lt;p&gt;In this configuration, we also create a topic named sample-topic4. We are using default Kafka properties here, this can be modified by adding the properties in the applciation.yml file.&lt;/p&gt;

&lt;p&gt;Next, let’s write the consumer class that will read data from the “sample-topic4” topic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@KafkaListener(id = "sampleGroup", topics = "sample-topic4", containerFactory = "jsonKafkaListenerContainerFactory")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, id represents the groupid. multiple consumers can read from a single topic, this is made possible by assigning each consumer to a different groupid. one consumer from each groupid will read the message from a given topic.&lt;/p&gt;

&lt;p&gt;If we are implementing a deserialization behavior then we will have to explicitly mention that in the KafkaListner annotation, else the default deserialization technique will be used.&lt;/p&gt;

&lt;p&gt;Next, let's create an API which upon being called will write a message to the Kafka topic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@PostMapping(path = "/send/{name}")

**public**  **void** sendFoo(@PathVariable String name) {

**this**.template.send("sample-topic4", **new** Sample(name));

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

&lt;/div&gt;



&lt;p&gt;Now, that we have most of the pieces in place, let’s create a POJO and then build and run this app.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing
&lt;/h4&gt;

&lt;p&gt;Test the app using the below curl&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --location --request POST 'localhost:8080/send/test' \

--header 'Content-Type: application/json' \

--data-raw '{}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we can verify the console logs to check the messages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[2m2022-01-28 15:49:51.739[0;39m [32m INFO[0;39m [35m88907[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.kafka.common.utils.AppInfoParser [0;39m [2m:[0;39m Kafka version: 3.0.0

[2m2022-01-28 15:49:51.740[0;39m [32m INFO[0;39m [35m88907[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.kafka.common.utils.AppInfoParser [0;39m [2m:[0;39m Kafka commitId: 8cb0a5e9d3441962

[2m2022-01-28 15:49:51.740[0;39m [32m INFO[0;39m [35m88907[0;39m [2m---[0;39m [2m[nio-8080-exec-2][0;39m [36mo.a.kafka.common.utils.AppInfoParser [0;39m [2m:[0;39m Kafka startTimeMs: 1643406591739

[2m2022-01-28 15:49:51.757[0;39m [32m INFO[0;39m [35m88907[0;39m [2m---[0;39m [2m[ad | producer-1][0;39m [36morg.apache.kafka.clients.Metadata [0;39m [2m:[0;39m [Producer clientId=producer-1] Cluster ID: G6ipFFHMTKqR9YoeXBHeIA

Received: hello

Received: test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;We have developed and tested Kafka messaging using spring-kafka.&lt;/p&gt;

&lt;p&gt;Complete code is available on &lt;a href="https://github.com/rubykv/code-examples/tree/master/spring-kafka-demo"&gt;&lt;strong&gt;Github&lt;/strong&gt;&lt;/a&gt;. Leave a star on the repository if you find the code useful.&lt;/p&gt;




</description>
      <category>springboot</category>
      <category>kafka</category>
      <category>programming</category>
      <category>java</category>
    </item>
    <item>
      <title>Google maps has all the data to create a useful platform for travelers</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Sat, 05 Feb 2022 03:50:45 +0000</pubDate>
      <link>https://dev.to/rubyshiv/google-maps-has-all-the-data-to-create-a-useful-platform-for-travelers-5774</link>
      <guid>https://dev.to/rubyshiv/google-maps-has-all-the-data-to-create-a-useful-platform-for-travelers-5774</guid>
      <description>&lt;p&gt;Wouldn't google maps be a better space to socialize if they keep the navigation separate from the social side of the business and then design the social side of it better with a simpler interface?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>design</category>
      <category>google</category>
      <category>ui</category>
    </item>
    <item>
      <title>How To Build, Run and Test a Simple SpringBoot App in Docker — Lab Test Style</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Thu, 03 Feb 2022 07:34:46 +0000</pubDate>
      <link>https://dev.to/rubyshiv/how-to-build-run-and-test-a-simple-springboot-app-in-docker-lab-test-style-3id9</link>
      <guid>https://dev.to/rubyshiv/how-to-build-run-and-test-a-simple-springboot-app-in-docker-lab-test-style-3id9</guid>
      <description>&lt;h3&gt;
  
  
  How To Build, Run and Test a Simple SpringBoot App in Docker — Lab Test Style
&lt;/h3&gt;

&lt;p&gt;Grab a cup of coffee like the little girl here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javarevisited.blogspot.com/2019/05/top-5-courses-to-learn-docker-and-kubernetes-for-devops.html"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FdcpcKd2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AXhwVENTm3mzpEl24C95Fzg.png" alt="" width="880" height="704"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have tried to install and run docker 3 times earlier but every time I failed, either there wasn’t enough memory on my laptop or the configuration was not proper on my windows machine. Installing &lt;a href="https://medium.com/javarevisited/top-15-online-courses-to-learn-docker-kubernetes-and-aws-for-fullstack-developers-and-devops-d8cc4f16e773"&gt;Docker&lt;/a&gt;on a windows machine gave me a headache so this time I tried to install docker on iMac, the main reason being, it had a little over 500 GB of memory unused. My laptop on the other hand, where I do all of my development work, is almost about to run out of memory.&lt;/p&gt;

&lt;p&gt;Coming back to the subject of discussion, this time &lt;a href="https://medium.com/javarevisited/top-5-free-courses-to-learn-docker-for-beginners-best-of-lot-b2b1ad2b98ad?"&gt;docker&lt;/a&gt;was installed successfully. It takes some time to install and docker desktop to come up so let the process run in the background when you can actually work on something else.&lt;/p&gt;

&lt;p&gt;There are plenty of resources out there to help with docker installation so we are not deep diving into that topic.&lt;/p&gt;

&lt;p&gt;While the software gets installed, let’s take a quick look at the docker concepts and refresh our memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.java67.com/2021/04/top-5-courses-to-learn-docker-for-java.html"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I4sg8Kj3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ALpaNz0WoZOpNlJVOduirFg.png" alt="" width="880" height="586"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Docker helps to configure and scale applications quickly&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Another important component here is Docker Hub. Just like &lt;a href="https://medium.com/javarevisited/how-to-perform-http-calls-using-spring-resttemplate-d29116cd4b5a?source=post_recirc---------0------------------"&gt;Github&lt;/a&gt;stores all the software code, docker hub stores docker images that are available for the public to use.&lt;/p&gt;

&lt;p&gt;Now, let’s approach this tutorial as a laboratory experiment and list down the prerequisites and the expected output before we start the work.&lt;/p&gt;
&lt;h4&gt;
  
  
  Requirements
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;1 Computer with docker installed. Do not install Java or any build tools here. (acts as a deployment environment)&lt;/li&gt;
&lt;li&gt;1 computer with &lt;a href="https://medium.com/javarevisited/7000-free-pluralsight-courses-to-build-in-demand-tech-skills-without-leaving-your-house-40edb50a8cf2"&gt;Java&lt;/a&gt; and &lt;a href="https://medium.com/javarevisited/6-best-maven-courses-for-beginners-in-2020-23ea3cba89"&gt;Maven&lt;/a&gt;installed. (It’s good to have an IDE for the code tweaks we will make to the &lt;a href="https://www.java67.com/2018/05/difference-between-springbootapplication-vs-EnableAutoConfiguration-annotations-Spring-Boot.html"&gt;spring-boot application&lt;/a&gt; but it’s optional.) — acts as a development environment.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Alternative Requirements
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;1 Computer with &lt;a href="https://medium.com/javarevisited/top-10-free-courses-to-learn-jenkins-docker-and-kubernetes-for-devops-in-2020-best-of-lot-62a0541ffeb3"&gt;docker&lt;/a&gt;, &lt;a href="https://medium.com/javarevisited/10-best-places-to-learn-java-online-for-free-ce5e713ab5b2"&gt;Java&lt;/a&gt;, and &lt;a href="https://medium.com/javarevisited/6-best-maven-courses-for-beginners-in-2020-23ea3cba89"&gt;Maven&lt;/a&gt;installed.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Assumptions
&lt;/h4&gt;

&lt;p&gt;The system is connected to the Internet.&lt;/p&gt;
&lt;h4&gt;
  
  
  Expected Output
&lt;/h4&gt;

&lt;p&gt;Run SpringBoot app in Docker. The app should expose a get API “/hello”. Return message has to be pleasant. eg: Hello World.&lt;/p&gt;
&lt;h4&gt;
  
  
  Steps
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a SpringBoot application from the “spring initializr” portal (start.spring.io). Add web as a dependency and packaging as “jar”. Choose build tool as maven. (Based on the developer's preference, this project can be built using &lt;a href="https://medium.com/javarevisited/5-best-gradle-courses-and-books-to-learn-in-2021-93f49ce8ff8e"&gt;Gradle&lt;/a&gt;as well but we will be using &lt;a href="https://javarevisited.blogspot.com/2020/06/maven-vs-gradle-beginners-introduction.html#axzz6dHZ7oEpK"&gt;Maven&lt;/a&gt;in this article)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the code and import it to STS or any similar IDE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify pom.xml, update the version as 0.0.1 by removing the SNAPSHOT extension (optional step)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a “/hello” endpoint in the main class&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Build and run the app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Access the endpoint at port 8080&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.java67.com/2019/07/spring-boot-3-ways-to-change-port-of-tomcat.html"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--79lF387x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AfB29G4fd3chAPvnWEhzb9Q.png" alt="" width="880" height="161"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;HTTP API accessed on port 8080&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Dockerfile in the spring-boot project. This file should not have any extension. A Dockerfile is a simple file that contains the steps to create a docker image. Docker builds the image using the commands contained in this file.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Commands Explained
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;FROM openjdk:8-jdk-alpine — &lt;/strong&gt; FROM is the command that is followed by the image name. This means, our image has to be created by keeping the “openjdk:8-jdk-alpine” image as the parent. “openjdk:8-jdk-alpine” is an image available in the Docker hub. All Images in &lt;a href="https://medium.com/javarevisited/5-best-docker-courses-for-java-and-spring-boot-developers-bbf01c5e6542"&gt;docker&lt;/a&gt;are either created from a parent image or from a base image (that the user has to create — Base Image starts with “FROM scratch”).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;COPY&lt;/strong&gt;  — This command instructs that the jar created under the target folder needs to be copied into the &lt;a href="https://javarevisited.blogspot.com/2018/02/10-free-docker-container-courses-for-Java-Developers.html#axzz5XlFjtjA0"&gt;docker container&lt;/a&gt; as demo.jar&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ENTRYPOINT — &lt;/strong&gt; This allows to specify the instructions as parameters to run an executable. eg: java -jar demo.jar is how we would run a jar in the command prompt.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build a docker image and run the container&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;a)If two computers are involved in this experiment, copy the project folder to the computer that has docker installed. Start docker app.&lt;/p&gt;

&lt;p&gt;b) If only one computer is being used, start the docker app on the same computer.&lt;/p&gt;

&lt;p&gt;Open a terminal from the project directory and type the below commands,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javarevisited.blogspot.com/2018/02/10-free-docker-container-courses-for-Java-Developers.html#axzz5XlFjtjA0"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RVhPDjsJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/735/1%2ARJ-I8eQ-ahMLb4IEJri7iA.png" alt="" width="735" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Commands Explained
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;docker build -t demodocker:1 .&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;build -t &lt;/strong&gt; — builds a docker image and tags it to the value that follows -t&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;demodocker:1&lt;/strong&gt;  — demodocker is the image name and 1 is the version of this image. This version could be incremented for future images of the same application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dot (.)&lt;/strong&gt; — do not miss the dot. It indicates that the Dockerfile is in the current directory.&lt;/p&gt;

&lt;p&gt;2.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;run&lt;/strong&gt;  — run the docker image&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-d&lt;/strong&gt;  — run the image in detached mode. The container will run in the background and the terminal is free to be used for other operations like checking logs, finding all the containers, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;name&lt;/strong&gt;  — the name of the container. Without this identifier, we will have to identify the containers based on the container id which is auto-created by the docker and hard to recognize from one another.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-p&lt;/strong&gt;  — this is a command to bind the port available in docker to that of the computer that’s hosting the docker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;demodocker:1 &lt;/strong&gt; — Image name that we created in the previous step.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;docker ps -a&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;ps -a&lt;/strong&gt;  — lists all the containers that are currently running and historical.&lt;/p&gt;

&lt;p&gt;We can find our image in the running status. Next, let’s test the application.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Access the “/hello” API on the computer that’s running docker.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Q8DKwmz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/702/1%2AYNVMJD27ESvbfOi5nbbxeA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Q8DKwmz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/702/1%2AYNVMJD27ESvbfOi5nbbxeA.png" alt="" width="702" height="159"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;/hello API accessed at port 8080 of the local machine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Justifying the two computer approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It was much easier to understand the advantages of using docker. On the iMac, I just had to install docker and run the image, and the spring-boot app was up and running in a few minutes.&lt;/p&gt;

&lt;p&gt;It's pretty much like replicating a real scenario where the deployment environment doesn't have to install any software that’s recommended for software development.&lt;/p&gt;

&lt;p&gt;The same would be the case when a new member joins the team, the entire workspace can be set up in a few minutes with a few images running on docker.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Actual Output = Expected Output&lt;/p&gt;

&lt;p&gt;Complete code for this project is available on &lt;a href="https://github.com/rubykv/code-examples/tree/master/demo"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;




</description>
      <category>java</category>
      <category>springboot</category>
      <category>docker</category>
      <category>spring</category>
    </item>
    <item>
      <title>Tech Recruiters Should Get Rid of These Outdated Ways to Assess Candidates</title>
      <dc:creator>Ruby Valappil</dc:creator>
      <pubDate>Fri, 28 Jan 2022 13:41:21 +0000</pubDate>
      <link>https://dev.to/rubyshiv/tech-recruiters-should-get-rid-of-these-outdated-ways-to-assess-candidates-amf</link>
      <guid>https://dev.to/rubyshiv/tech-recruiters-should-get-rid-of-these-outdated-ways-to-assess-candidates-amf</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cK8yyLhU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ay7TwupwaoWMPeYNHYOlQHQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cK8yyLhU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ay7TwupwaoWMPeYNHYOlQHQ.jpeg" alt="_Photo by LinkedIn Sales Solutions on Unsplash_" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1. Ignoring Resume&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;If the interview starts with asking the candidate’s years of experience in so and so technology then it implies that the recruiter has not reviewed the candidate’s resume. &lt;/p&gt;

&lt;p&gt;That's either an insult to the candidate or shows a broken process at the recruiter's end. If the resume is to be discarded then why care to ask for one in the first place? Fix the attitude or fix the process.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;2. Copy questions from the internet&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;A technical recruiters job is to evaluate the candidate on one of the two criteria’s,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is she/he equipped with the necessary skills that the job demands?&lt;/li&gt;
&lt;li&gt;Will she/he scale up to the job demands?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To answer these questions, one needs to ask questions that are relevant to the job description and relevant to the experience of the candidate. Internet is not the place to decide that. Sure one can refer to the questions posted on various blogs but do not blindly copy-paste them from the web.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;3. Test Memory Over Understanding&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u3HfDsqk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A0fUTPc01FIsWnmBPFucc2Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u3HfDsqk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A0fUTPc01FIsWnmBPFucc2Q.png" alt="memory" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Testing the candidate’s memory is not going to help either side.&lt;/p&gt;

&lt;p&gt;I have interviewed junior developers who understand how certain frameworks work but do not remember certain terms by heart, more so because of the nervousness I believe but even otherwise it's not a sin to not remember method names by heart, we all use IDE’s right?&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;4. Counting years of experience&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;10 years of experience in so and so technology, if not, even a brilliant candidate is rejected.&lt;/p&gt;

&lt;p&gt;Why exactly do those years of experience even matter? There have been hilarious instances where the number of years required for a job was more than the years the tech was available in the market.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;5. Ignoring Candidates Attitude&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pFeU2Ugf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Aws1Z7GNEABIj4qYJ_uG4Qg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pFeU2Ugf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Aws1Z7GNEABIj4qYJ_uG4Qg.png" alt="attitude" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Skill and experience can be acquired over time but the attitude of a candidate matters a lot. Is she/he eager to learn, do they like to find ways to automate redundant manual tasks, how much time have they invested to upskill themselves, do they experiment with different tech stacks other than the job requirements?&lt;/p&gt;

&lt;p&gt;This analysis helps to identify a candidate who is passionate about the work from those who just want to do the bare minimum and go home. Now again, if “bare-minimum-attitude” is what the company is looking for, then spare other candidates who prefer deep work from the pain of working with mediocres.&lt;/p&gt;




</description>
      <category>blog</category>
      <category>software</category>
      <category>jobs</category>
      <category>recruitment</category>
    </item>
  </channel>
</rss>
