Pages

Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Friday, February 28, 2020

Intro to Apache Kafka with Spring

In this application I am creating a simple java micro service that consumes from a kafka topic.
This implementation uses the spring-kafka framework. The code for this example can be found here: https://github.com/SFRJ/offerskafka


Saturday, November 9, 2019

Switch between Java versions using an alias in ubuntu

If you work in a micro-services environment or other type of back end distributed system, it is not rare to see applications running with different versions of Java. In this blog post I am going to show, how you can setup your linux/ubuntu development machine to quickly switch between Java versions.

Let's start by assuming, you don't have any Java installed. We are going to first install 2 versions of Java; openjdk 8 and openjdk 11.

To do so open a terminal and just type this command to install openjdk8:
sudo apt install openjdk-8-jdk

The installation process should be straight forward, just choose the 'Y' option when prompted.
Once is completed, check the java version
java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b03-0ubuntu1.18.10.1-b03)
OpenJDK 64-Bit Server VM (build 25.212-b03, mixed mode)

Now let's install openjdk 11
sudo apt install openjdk-11-jdk

Check the version again
java -version
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment (build 11.0.3+7-Ubuntu-1ubuntu218.10.1)
OpenJDK 64-Bit Server VM (build 11.0.3+7-Ubuntu-1ubuntu218.10.1, mixed mode, sharing)

Now you have 2 versions of the JDK installed. You can see all the java versions you have by running this command:
update-java-alternatives --list
java-1.11.0-openjdk-amd64      1111       /usr/lib/jvm/java-1.11.0-openjdk-amd64
java-1.8.0-openjdk-amd64       1081       /usr/lib/jvm/java-1.8.0-openjdk-amd64

If you want you can ls into the jvm directory

ls -l
lrwxrwxrwx 1 root root   25 Sep 20  2018 default-java -> java-1.11.0-openjdk-amd64
lrwxrwxrwx 1 root root   21 Apr 23  2019 java-1.11.0-openjdk-amd64 -> java-11-openjdk-amd64
drwxr-xr-x 9 root root 4096 Nov  9 08:49 java-11-openjdk-amd64
lrwxrwxrwx 1 root root   20 Jan 14  2019 java-1.8.0-openjdk-amd64 -> java-8-openjdk-amd64
drwxr-xr-x 7 root root 4096 Nov  9 10:13 java-8-openjdk-amd64

Note that there are some useful simlinks that you could use to refer to the version you want when configuring. But for the scope of this blog I will be using directly the folder names.

A way to manually change the java versions is to just run this:
sudo update-alternatives --config java
[sudo] password for computername: 
There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
  0            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      auto mode
* 1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      manual mode
  2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      manual mode

Press <enter> to keep the current choice[*], or type selection number: 

To change the version of the compiler you can use the same command but with javac instead

sudo update-alternatives --config javac
There are 2 choices for the alternative javac (providing /usr/bin/javac).

  Selection    Path                                          Priority   Status
------------------------------------------------------------
  0            /usr/lib/jvm/java-11-openjdk-amd64/bin/javac   1111      auto mode
* 1            /usr/lib/jvm/java-11-openjdk-amd64/bin/javac   1111      manual mode
  2            /usr/lib/jvm/java-8-openjdk-amd64/bin/javac    1081      manual mode

Press <enter> to keep the current choice[*], or type selection number: 

But also that's not all, the JAVA_HOME environment variable also needs to be configured. This environment variable is often used by the IDE and other Java technologies tools so it needs to be configured. As you can now see, if you wanted to quickly switch version, this would actually still be slow. Now I am going to explain how to complete the setup for q quick switch between java versions.

Make sure to create the JAVA_HOME variable configured system wide. If is not there make sure you edit that file and you add it.
cat /etc/environment 
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64/"

 Notice that I didn't wire the JAVA_HOME into the PATH in there, the reson is because i like to do that in my local .bashrc file. In this file also I have maven, aliases and other things that I think is better not to open system wide.

cat ~/.bashrc
export M2_HOME=/home/javing/maven
export M2=$M2_HOME/bin
export PATH=$JAVA_HOME/bin:$M2:$PATH

All we need now, is some aliases that can help us switch between java versions and at the same time configure the JAVA_HOME variable. Add this to the .bashrc files

#My aliases
alias jv='java -version'
alias j8='sudo update-java-alternatives -s java-1.8.0-openjdk-amd64;jv;homej8'
alias j11='sudo update-java-alternatives -s java-1.11.0-openjdk-amd64;jv;homej11'
alias homej8='export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/;echo $"JAVA_HOME set to:";echo $JAVA_HOME;s'
alias homej11='export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/;echo $"JAVA_HOME set to:";echo $JAVA_HOME;s'
alias s='source ~/.bashrc'

Note that the command update-java-alternatives will update both the compiler and the jvm versions, in my config I am using the directory name rather than the simlink. to test this just type in the terminal the aliases j8 or j11 to switch between jdk's.
Usage example:

j11
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment (build 11.0.3+7-Ubuntu-1ubuntu218.10.1)
OpenJDK 64-Bit Server VM (build 11.0.3+7-Ubuntu-1ubuntu218.10.1, mixed mode, sharing)
JAVA_HOME set to:
/usr/lib/jvm/java-11-openjdk-amd64/bin/


Now, you are all set and ready for Javing! ;)

Sunday, June 16, 2019

Enhance your functional java experience with VAVR

In this video I briefly show some features that Vavr has and Java-8 doesn't.




Code examples: https://github.com/SFRJ/vavrExamples

Tuesday, January 8, 2019

Monday, December 17, 2018

Java Developer interview questions.

I decided to make a compilation of possible interview questions for Java developers. I personally don't really like when in interviews this kind of academically oriented questions appear but unfortunately not every company does live coding exercises.

Hopefully this blog post will be useful as a mind refreshing tool when going to one of those interviews where the interviewer reads questions from a script(sometimes managers or semi-technical tech leads, etc ...) and you have to explain technical things with your own words. 

This compilation are real questions that can appear and they did in fact appear in interviews I've been in, at some point in my career. I will try to include more questions to this video in the future as I remember them.

For Kafka related F.A.Q have a look at
http://javing.blogspot.com/2020/02/kafka-faq.html


What is the equals and hashcode contract in Java?


What is the difference between an ArrayList and a Linked list?


What is the final keyword in java and where it can be used?

Can you describe the inner workings of a Java HashMap?


What is "try with resources" in Java? 


Do you know what "volatile" is?


Can you write code to check if a String is a Palindrome?


How can you reverse a String using Java?


How can you reverse an Integer using Java?

@Component vs @Service vs @Repository



What is database indexing?


Explain asynchronous non blocking calls and what are circuit breakers
                    








Java 8 Refactoring Part 5: Improving enum with a BiFunction

This is the last refactoring that Victor Rentea did in the devoxx conference in London. He used a BiFunction to be able to provide more flexibility to an Enum. A very interesting refactor.



Thursday, December 13, 2018

Java 8 Refactoring Part 4: Composition Over Inheritance using the Loan Design Pattern

The Loan design pattern is a pattern that follows the principle of favouring composition over inheritance. It was explained in the Devoxx conference in London.



Wednesday, December 12, 2018

Java 8 Refactoring Part 3: Removing null checks and introducing Optional

The Optional feature of Java 8 it's very powerful it can prevent lot's of bugs and also make our code look more tidy. In this video I show an example which is very similar to the one presented at Devoxx London in 2018 by V. Rentea


Sunday, December 9, 2018

Java 8 Refactoring Part 2: Stream Wrecks

A stream wreck is a complex concatenation of streams that tries to provide some results in a one-liner. One-liners are good but concatenation of Streams is not good since makes the code quite difficult to follow. To fix stream wrecks we need to extract methods, local variables or classes in order to be able to improve the readability of the code.


Saturday, December 8, 2018

Java 8 Refactoring Part 1: Extracting Anonymous function to it's own class

In this video I mimic the first of the design patterns presented by Victor Rentea in the Devoxx conference in London in 2018.


Perhaps worth mentioning that the advantages of extracting anonymous functions into separate classes are:

- better readability of the code
- code easier to test
- more maintainable code

Tuesday, September 11, 2018

AspectJ + Custom Annotation + Gradle (Without Spring)

Recently I had to create an aspect to run before and after an annotated method was executed.
The first thing I thought was to just use Spring, but I was told that the devices where this software was going to run have limited resources so Spring would not an option because of it's large memory footprint.

After looking around the internet for a while I decided to do it just by using the aspectJ framework on it's own.

This is how I configured my gradle file
group 'com.javing.customAnnotations'
version '1.0-SNAPSHOT'

project.ext {
    aspectjVersion = '1.8.4'
}

apply plugin: 'java'
apply plugin: 'aspectj.gradle'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "gradle.plugin.aspectj:gradle-aspectj:0.1.6"
    }
}

dependencies {
    compile 'org.aspectj:aspectjrt:1.8.4'
    compile 'org.aspectj:aspectjweaver:1.8.4'
    compile 'org.aspectj:aspectjtools:1.8.4'
    compile 'junit:junit:4.12'
}


I created a custom annotation which will later allow me to trigger the aspect.
package spike;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HelloAnnotation {

    public boolean isRun() default true;

}


I placed the annotation on the methods I want the aspect to run around
package spike;

public class HelloApp {

    public static void main(String[] args) {
        HelloApp helloApp = new HelloApp();
        helloApp.work();
    }

    @HelloAnnotation
    public void work() {
        System.out.println("Hello world!");
    }
}


Finally I created the logic of the aspect
package spike;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class HelloAspect {

    @Around("execution(* *(..)) && @annotation(spike.HelloAnnotation)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("Before");
        Object proceed = pjp.proceed();
        System.out.println("After");
        return proceed;
    }

}

In order to see this working in the IntelliJ editor you have to make sure you enable the Gradle Test Runner.



Wednesday, August 8, 2018

Using Wiremock to simulate a slow responding server.

Here a little example of a stub created with Wiremock that simulates a slow reply from a server:

 import com.github.tomakehurst.wiremock.WireMockServer;  
 import java.util.Scanner;  
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;  
 import static com.github.tomakehurst.wiremock.client.WireMock.get;  
 import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;  
 public class FakeThirdPartySystem {  

   public static void main(String[] args) {  
     WireMockServer server = new WireMockServer(8081);  
     server.start();  
     server.stubFor(get(urlEqualTo("/someUrl"))  
         .willReturn(aResponse()  
             .withStatus(200)  
             .withFixedDelay(10000)  
             .withBody("Slow reply!")));  

     //This is just so that the app doesn't exit straight away
     Scanner scanner = new Scanner(System.in);  
     System.out.println("Press enter to exit");  
     scanner.nextLine();  
     server.stop();  
   }  

 }  

Note: This is just for illustration purposes but this same way of stubbing can be added to an acceptance test. 

Tuesday, April 24, 2018

VAVR - Using map(), flatMap(), Option and Try to get different return types

Simple map() operation in vavr.io takes as argument a function that has as a parameter the type of element contained in the list. The return type of the method in the function can be anything we want. The purpose of map is to transform from one type to another.

public List<BigDecimal> simpleMap(List<Integer> numbers) {
      return numbers.map(n -> m1(n));
   }

    private BigDecimal m1(Integer i) {
     return new BigDecimal(i);
   }


flatMap() uses the same mechanics as map but the only difference is that it will remove the duplication by collapsing the duplicates into a single entry. e.g 1,2,2,2,3 flatMapped will become 1,2,3
public List<BigDecimal> flatMapping(List<Integer> numbers) {
    return numbers.flatMap(n -> m2(n));
   }

   private List<BigDecimal> m2(Integer i) {
     return List.of(new BigDecimal(i));
   }

Sometimes a function can return List<Try<Option<?>>>> that is fine but perhaps Option is sometimes redundant. Notice that this method uses Try<Option>, that looks a bit overkill
public List<Try<Option<String>>> returningARedundantOption(List<Integer> numbers) {
        return numbers.map(n -> m3(n));
    }

    private Try<Option<String>> m3(Integer i) {
        //Imagine this option is the result of intereacting with other code
        // e.g some dao object
        return Try.success(Option.some(""));
    }

To solve the redundancy shown in the example above, we can perform an additional flatMap() so that we get rid of the Option by mapping it to a Try using the toTry() method inside Option. This way we get a List<Try<String>>.
public List<Try<String>> removingRedundancy(List<Integer> numbers) {
        return numbers.map(n -> {
            return m3(n).flatMap(Option::toTry);
        });
    }
    //Same as above
    public List<Try<String>> removingRedundancy(List<Integer> numbers) {
        return numbers.map(n -> m3(n).flatMap(Option::toTry));
    }

    private Try<Option<String>> m3(Integer i) {
        return Try.success(Option.some(""));
    }

In this final example we map a set of integers to a Try<Option<String>> and then we flatMap the result to Set<Try<String>> in order to transform that Set<Try<String>> into a Try<List<String>> we pass the result to Try.sequence() and we map the outcome to list.
public Try<List<String>> usingSequence(Set<Integer> ids) {
        Set<Try<String>> result = ids.map(id -> m4(id).flatMap(Option::toTry));
        return Try.sequence(result).map(Seq::toList);
    }

    //Same as above
    public Try<List<String>> spike2(Set<Integer> ids) {
        return Try.sequence(ids.map(id -> m4(id).flatMap(Option::toTry))).map(Seq::toList);
    }

    private Try<Option<String>>  m4(Integer id) {
        Try.success(Option.of("something" + id));
    }

For more information about the vavr.io framework: http://www.vavr.io/

Wednesday, August 23, 2017

Dockerizing a modern Java application


In this video I show the structure of a modern Java web application that uses Spring boot, Spring mvc, gradle, angularjs and then I will show how it is commonly prepared to run from within a docker container.




Full Source codes: https://github.com/SFRJ/tictactoe

Thursday, April 20, 2017

Browser automation in Java using Cucumber and Selenium


This is video I created to explain some of the very basics of browser automation in Java. Using the the classic tools Cucumber and Selenium.


Thursday, April 13, 2017

Implementing Strategy Design Pattern(Practical example)

In this video I show how to refactor some ugly if-else nested statements using polymorphism through the strategy design pattern.

Please note that I didn't use code coverage in this occasion, this was more of an Spike than a refactor I would say. My goal was to just show the implementation of the pattern and make a brief video. Of course if you are trying this in real software, please make sure that your code is covered by unit tests before proceeding.




Tuesday, April 11, 2017

Checking that 2 Lists have elements in common

How many times have we created loops to check if any of the elements of one list are contained among any of the elements of other list?

Lists have a contains() and also a containsAll() methods but they doesn't seem to do what we want and we end up writing spaghetti that looks like this often:

1:  boolean isSafeToEat(List<String> allergicFoods) {  
2:    for (String ingredient : getIngredients()) {  
3:      if (allergicFoods.contains(ingredient)) {  
4:        return false;  
5:      }  
6:    }  
7:    return true;  
8:  }  


Sometimes we forget that the Java API has so many useful things. Like this disjoint() method, from Collections.

1:    boolean isSafeToEat(List<String> allergicFoods) {  
2:      return Collections.disjoint(ingredients, allergicFoods);  
3:    }  

Its not Java 8 ;) its being there for a bit already, have a look at this docs:
https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#disjoint(java.util.Collection,%20java.util.Collection)

Refactor switch to Enum

Do switch statements sound good to you? 
Trust me better switch to Enum before it destroys your ears ;)



Monday, April 10, 2017

Mocking static method calls

Very simple example on how we can use method delegation to enable unit testing where there is a dependency to an static method call.



Friday, April 7, 2017

Refactoring "Feature Envy" Code Smell

In this video I explain the "Feature Envy" Code Smell and how it can be refactored. Sorry I made a mistake in the screen casts and I just selected the window rather than the area, you can't see the pop up menus and auto suggest when I press Ctrl + Space. Sorry about that :(( It takes me some time to make videos but if I get the chance soon I will repeat the demo and re-upload it.


Share with your friends