Pages

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

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! ;)

Monday, December 17, 2018

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


Tuesday, March 28, 2017

13 minutes TDD warm up

O wow! I haven't realised for how long I didn't write a blog post.  I better start posting again, but first... Let's warm up with a bit of TDD. Ok I've got 13 minutes, lets put on some music and see if I can do a Kata.

Note: To view in high resolution, open the full screen view and change the video quality using the wheel.

                                           
    The video is raw unedited, the music is coming from youtube in my second screen.13 roman digits, parsed in 13 minutes ;)


Thursday, September 24, 2015

First class functions Vs Higher order functions

First class functions means the ability to treat a function as a value, assigning it to a variable, or passing it as an argument to another function.

 //example 1 assignment  
   Function<String,String> postfixFunction = s -> s + "-postfix";  
 //example 2 passing as parameter  
   public void someMethod() {  
     stringManipulator(postfixFunction, asList("A","B"));  
   }  

A higher order function is a function that accepts other functions as arguments, or returns another function.

  //example 1 accepting function as arguments  
   public List<String> stringManipulator(Function<String, String> manipulator, List<String> data) {  
     return data.stream().map(manipulator).collect(toList());  
   }  
   //example 2 returning a function  
   public Function<String, String> postfixFunction() {  
     return s -> s + "-postfix";  
   }   

Wednesday, October 29, 2014

Indaface!



Recently my team leader gave me an S.L.A.P, hehehe...
Don't worry this is not a case of bullying, it just a way of refering to an important Object Oriented Principle known as the Single Level of Abstraction Principle.
As Usual at the office paring on an story, when we got to the refactoring bit, I was told to improve a method that had some ugly conditional logic on it, and also some duplication.
Instead of removing the duplication, I just delegated all the problematic part to another method, so the original method would look smaller and cleaner, but...
He said to me: Do you think that code you just delegated is located now at a different level of abstraction?... Indaface! Violation of S.L.A.P
Below, an example that somehow recreates todays funny situation :P Sorry, can't show you the real code(Dont wanna get in trouble :) ).

 /*  
     We have a vault that its being populated and categorized but there is a little 
     duplication issue when populating the vault with CAT-3 items. Items withGrook() 
     are definitely CAT-3, but those withTrook() are only categorized as CAT-3 if 
     klop.isHigh().   
 */  
    public Vault stuff(Klop klop, Vault vault) {  
     vault.include("CAT-1", azra());  
     vault.include("CAT-2", khy());  
     vault.include("CAT-3", things.stream().filter(withGrook()).
     map(toSponge()).map(toPlik(klop)).collect(toList()));  
     if(klop.isHigh())  
       vault.include("CAT-3", things.stream().filter(withTrook()).
       map(toSponge()).map(toPlik(klop)).collect(toList()));  
     return vault;  
     }  
 /*  
     At the beggining we may feel tempted to extract that vault.include, to its own
     method which will be specific to CAT-3 items, regardles that the stuff method looks
     shorter, the problem is that we did not remove the duplication plus we are disrespecting
     the S.L.A.P principle.  
 */      
      public Vault stuff(Klop klop, Vault vault) {  
           vault.include("CAT-1", azra());  
           vault.include("CAT-2", khy());  
           includeCat3Items(vault,klop);  
           return vault;  
        }  

   private void includeCat3Items(Vault vault, Klop klop) {  
           if(klop.isHigh())  
             vault.include("CAT-3", things.stream().filter(withGrook()).
             map(toSponge()).map(toPlik(klop)).collect(toList()));  
             vault.include("CAT-3", things.stream().filter(withTrook()).
             map(toSponge()).map(toPlik(klop)).collect(toList()));  
   }  
  
  /*If we want to respect S.L.A.P, in this case what we need to extract, is just the 
    changing part, and delegate the condition to check if klop.isHigh, to the delegate
     method.  
  */  
     public Vault stuff(Klop klop, Vault vault) {  
     vault.include("CAT-1", azra());  
     vault.include("CAT-2", khy());  
     vault.include("CAT-3", things.stream().filter(ook(klop)).
     map(toSponge()).map(toPlik(klop)).collect(toList()));  
     return vault;  
   }  

   private Predicate<String> ook(Klop klop) {  
     return klop.isHigh() ? withGrook(): withTrook();  
   }  

 /*  
     The final refactor could even go one step further by extracting implementation 
     detail into a plu(Klop klop) method  
 */      
   public Vault stuff(Klop klop, Vault vault) {  
     vault.include("CAT-1", azra());  
     vault.include("CAT-2", khy());  
     vault.include("CAT-3", plu(klop));  
     return vault;  
   }
  
   private List<Object> plu(Klop klop) {  
     return things.stream().filter(ook(klop)).map(toSponge()).map(toPlik(klop)).collect(toList());  
   }  
   private Predicate<String> ook(Klop klop) {  
     return klop.isHigh() ? withGrook(): withTrook();  
   }  


This post is dedicated to L.K, thanks for the patience :)

Share with your friends