Effective Java – Third edition​

​​

Effective Java is always a good book to read and this latest edition is no different. Here is the Amazon link to get the book. Here are some code samples and presentation promoting the book. My quick code snippet from the book.

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class StringManipLambda {
public static void main(String args[]){
 List stringArras= Arrays.asList("First","Second","third","fourth","fifth");
 Collections.sort(stringArras,(s1,s2)->Integer.compare(s1.length(),s2.length()));
 stringArras.stream().forEach(System.out::println);
    }
}

This is a simple code block, where we take a list of Strings and sort it based on its length. The book goes in depth of how to read this lambda expression and understand how it works.

 

Quickest way of getting an custom error message in Spring Boot 2.x

There are different ways to get a custom error message page in spring boot. The following solution worked for my web project. Here is the overview of the structure.

Pic Pic

To start with, if there is 404 error, then we want a custom error page showing up instead of the spring boot’s default page.
The first thing we are going handle is to suppress the boot framework’s error page. For this, we will go to the application properties and add the following line

server.error.whitelabel.enabled=false

As we are done with that, now let us implement the ErrorController interface. The thing to keep in mind is, we have the LOG entry that says what happened to the code base as we reached here. Here is the sample code.

 

@Controller
public class ITContractErrorController implements ErrorController     {
    public static final Logger LOG = LoggerFactory.getLogger(ITContractErrorController.class);
    @Autowired
    ErrorAttributes errorAttributes;
    @GetMapping({"${server.error.path:${error.path:/error}}"})
    public String handleError() {
        LOG.error("Sever error occured");
        return "/error/error.html";
    }
@Override
public String getErrorPath() {
    return "error";
    }
}

One other way that we can add the custom error message is using the Spring 2.x’s ConfigurableServletWebServerFactory implementation. We add this to the main method of the web module. Here is the sample code for this entry.

 

@SpringBootApplication
public class SkminfycontractorWebmoduleApplication {
    @Bean
    public ConfigurableServletWebServerFactory         containerCustomizer(){
        TomcatServletWebServerFactory factory = new     TomcatServletWebServerFactory();
        factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,     "/error/error.html"));
        return factory;
    }
    public static void main(String[] args) {
        SpringApplication.run(SkminfycontractorWebmoduleApplication.class, args);
    }
}

One thing to remember is, when we implement the override with ConfigurableServeletFactory then Override that is ErrorController is gone.

There is a lot of best practice information laid out in spring documentation and other places. But none worked for my setup. I will update this entry if I find a more interesting solution.

Spring 5 and JUNIT.

Let us try to put together some JUNITs with Spring 5 injection. One of the most challenging things of integrating JUnit and Spring was the role of the IDE. It is important to keep an eye on that.
So here is the code we are going to look.

    @RunWith(SpringJUnit4ClassRunner.class)@ContextHierarchy({
        @ContextConfiguration(classes = StreamsConfig.class)})
        
    public class StreamsFilterSampleTest {
    
      Logger LOG = getLogger(StreamsFilterSampleTest.class);
    
      @Autowired
      StreamsFilterSample streamFilterStream;
      @Autowired
      StreamstoListSample streamstoListSample;

      @Test
      public void testStreamGroupBy() throws Exception {
        LOG.debug("Debugging method start ==> testStreamGroupBy " + "with parameter []");
        streamFilterStream.streamGroupBy();
        LOG.debug("Debugging method end ==> testStreamGroupBy " + "with parameter []");
      }
    }

We see the definition starts with Spring configuration initialization. The annotation

@RunWith(SpringJUnit4ClassRunner.class)@ContextHierarchy({
    @ContextConfiguration(classes = StreamsConfig.class)})

RunWith, we are annotating it to be Spring JUnit. The code block is getting initialized with configuration class of StreamConfig. Now let us take a look at the StreamConfig definition

    @Configuration()
    @ComponentScan("streams")
    public class StreamsConfig {
    public static final Logger LOG = LoggerFactory.getLogger(StreamsConfig.class);
    @Autowired
    StreamsFilterSample streamFilterStream;
      public StreamsConfig() {
        LOG.debug("Constructing Config");
    }
    }

We are autowiring an implementation class, StreamFilterSample. This is just a utility class and code goes something like this.

    public void streamGroupBy() {
    //3 apple, 2 banana, others 1
    List<Item> items = Arrays.asList(
        new Item(null, 10, new BigDecimal("20.00")),
        new Item("apple", 10, new BigDecimal("21.00")),
        new Item("apple", 10, new BigDecimal("22.00")),
        new Item("banana", 20, new BigDecimal("19.99")),
        new Item("orang", 10, new BigDecimal("29.99")),
        new Item("watermelon", 10, new BigDecimal("29.99")),
        new Item("papaya", 20, new BigDecimal("9.99")),
        new Item("apple", 10, new BigDecimal("9.99")),
        new Item("banana", 10, new BigDecimal("19.99")),
        new Item("apple", 20, new BigDecimal("9.99"))
    );
    //group by price
    Map<BigDecimal, List<Item>> groupByPriceMap =
     items.stream().collect(Collectors.groupingBy(Item::getPrice));
    Map<String, List<Item>> groupByNameMap =
        items.stream().filter(item -> item.getName() != null).collect(Collectors.groupingBy
            (Item::getName));
    System.out.println(groupByNameMap);
    }
    private static class Item {
    private String name;
    private int qty;
    private BigDecimal price;
    public Item(String name, int qty, BigDecimal price) {
      this.name = name;
      this.qty = qty;
      this.price = price;
    }
    public Item(String name, BigDecimal price) {this.name = name;this.price = price;}
    public int getQty() {return qty;}
    public void setQty(int qty) {this.qty = qty;}
    public BigDecimal getPrice() {return price;}
    public void setPrice(BigDecimal price) {this.price = price;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    }

Now when we are running the JUnit, we have to make sure the @Test annotation is from the JUnit jar file. If you accidentally have the TestNG’s @Test annotation, it will not be able to understand the configuration that we have in the JUnit header. Finally, remember to make sure the IDE is not making anything goofy where it pulled a wrong Annotation class. Here is a useful Stackoverflow discussion on this.

Reads and links May 1st to May 15th 2018

Links Thoughts
Day one course Like Shawn’s material. I did not buy it, as am already a power user of Dayone. If you thinking about journaling, I would think this would be wonderful
Concurrency and Parallelism Simple explanation about the most powerful concepts in programming.
Kids view Another great writeup from NPR for
Startup ideas This was a good overview if ur in a startup. Not sure if I can translate this in a big shop where I’m used to.
GDPR Am sure am not alone in getting all GDPR privacy update emails. This link was a good overview.

JAVA 9 takeWhile and doWhile

Trying to get my hands wet with Java 9. Looks like the streams have got another round of good method updates. Here in this gist, we are trying to demonstrate the takeWhile and the dropWhile filter in the Java 9.
public static List createSong() {
return Arrays
.asList(new Song("Venilave", 2000, "Rehman"), new Song("Va Va Vasanthame", 2002, "Raja"), new Song("Vanjokotiya", 2010, "Raja"), new Song("semmaFigure", 2008, "Rehman"), new Song("Arabic kadloram", 2001, "Rehman"), new Song("Anjali Anjali", 1995, "Raja"), new Song("Pen alla Pen alla", 2010, "Rehman"));
}
public static void main(String args[]) {
createSong().stream().takeWhile(song -> song.getAlbumYear() System.out.println(song.getAlbumYear())).map(Song::getName)
.map(String::toUpperCase).forEach(System.out::println);
}

takeWhile method

Operates on a stream and in the code, we are trying to identify the songs that were from the year that is less than 2002. This condition qualifies only one record to be returned. The returned data is

2000
VENILAVE

dropWhile method

Aging this operates on a stream as well, and this one returns all the records whose album year is after 2002. So we get back the following records.

public class Song {
private String name;
private int albumYear;
private String genre;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAlbumYear() {
return albumYear;
}
public void setAlbumYear(int albumYear) {
this.albumYear = albumYear;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public Song(String name, int albumYear, String genre){
this.name=name;
this.albumYear=albumYear;
this.genre=genre;
}

2002
VA VA VASANTHAME
2010
VANJOKOTIYA
2008
SEMMAFIGURE
2001
ARABIC KADLORAM
1995
ANJALI ANJALI
2010
PEN ALLA PEN ALLA

 

Free-code camp Inventory update solution

One other interesting problem with the inventory update challenge from freecodecamp. After this, it is going to be the modules for creating calculators and other challenges.


function updateInventoryWithArr(curInv, newInv) {
    var arr1 = curInv;
    var arr2 = newInv;
    var finalOutPutArr = [];
    var arr1Map = new Map();
    var arr2Map = new Map();
    var arr3Map = new Map();
    for (var j = 0; j < arr1.length; j++) {
        var data1 = arr1[j][1];
        var data2 = arr1[j][0];
        arr1Map.set(data1, data2);
        arr3Map.set(data1, data2);
    }

    for (var i = 0; i < arr2.length; i++) {
        var keyVal = arr2[i][0];
        var lookupKey = arr2[i][1];
        var keyData = arr1Map.get(lookupKey);
        var sumVal;
        if (typeof keyData != 'undefined') {

            sumVal = keyVal + keyData;
            arr3Map.set(arr2[i][1], sumVal);
            arr2Map.set(sumVal, arr2[i][1]);
        } else {
            arr3Map.set(arr2[i][1], keyVal);
            arr2Map.set(keyVal, arr2[i][1]);
        }

    }

    var dataInf = Array.from(arr3Map);
    for (var k = 0; k  b[1]
    });
    return finalOutPutArr;
}