SpEL introduction - part 1

SpEL is a powerful utility framework provided by spring for looking up object graph. We will take a look at how to use spEL in this post. We will divide this article into two parts.

We will first create a simple object and see how SpEL is used for reading and manipulating the object graph and then in the second part of the article, we will define a properites file. Read the properties and assign it to a object variable.

SpEL expression evaluation interface

We will take take a simple object here and see how to use the expression api's to manipulate the object.


public class SampleProgrammer{
        public String name;
        public String occupation
        @Autowired
        SampleProgrammer(String name, String occupation) {
            this.name = name;
            this.occupation = occupation;
        }
}

Now we will create the object and see how to parse the object using SpEL.


       ...
        SampleProgrammer programmer = new SampleProgrammer("Sathish Jayapal", "Programmer");
        ExpressionParser expressionParser = new SpelExpressionParser();
        Expression nameExpression = programmer.parseExpression("name");
        Expression occupExpression = programmer.parseExpression("occupation");
     // EvaluationContext context = new StandardEvaluationContext(programmer);
        String name = (String) nameExpression.getValue(programmer);
        String occupation = (String) occupExpression.getValue(programmer);
        if (logger.isDebugEnabled()) {
            logger.debug("Context Name is " + name);
            logger.debug("Context Occupation is " + occupation);
        }

Looking at the code snippet above, there are few items that we can discuss. We create an Object of the Programmer and manipulate the object tree dynmaically. We are using the expression and its sublass SpelExpressionParser parser. There are two items in the SamplePrgorammer's programmer object. They are name and occupation. We will define an expression for each class variable. After this we use the expression class to get the value parsed. Here is the code snippet for this :


        ...
        Expression nameExpression = expressionParser.parseExpression("name"); // Define name for expression
        ...
       String name = (String) nameExpression.getValue(programmer);
       ...
       if (logger.isDebugEnabled()) {
            logger.debug("Context Name is " + name);
        ...
        }

We will discuss the reason why this following line of code is commented out.

// EvaluationContext context = new StandardEvaluationContext(programmer);

StandardEvaluationContext uses reflection API's to identify the constructors and methods. But this is a costly object, in our example we can quickly use the getValue method to get the value.

SpEL by default is interpreter based, all expression are interpreted for evaluation. The reason for this is to give flexibility during evaluation. But if the expression evaluation is not changing often, we can switch the expression to be compiled to JAVA Class. This switch can be done using the [SpringCompilerMode][1] enum parameter. There are few available modes to operate, it is OFF, IMMEDIATE and MIXED. By default SpEL has this in the OFF mode. Immediate mode ensures that expressions are compiled right away. MIXED mode as name suggests expressions are switched between the compile and interepreter mode.

We saw a quick introduction of SpEL and some basic operation in this post. In the next part we will use SpEL to read a properties file and evaluate values.

The sample code for this is in GitHub.

Using Spring AnnotationConfigApplicationContext

Overview

Using the AnnotationConfigApplicationContext

  • We will learn how to use the AnnotationApplicationContext. We are going to create a standalone spring application, using the AnnotationApplicationContext.
  • In this example, we have two classes:

Music Class:



@Component
public class Music {
    @Autowired private String genre;
    public void setGenre(String genre) {
        this.genre = genre;
    }
    @Override
    public String toString() {
    return "Music{" + "Genre='" + genre + '\'' + '}';
    }
} 

Piano class:


@Component
public class Piano {
    @Autowired
    private Music rawMusic;
    private String numberOfKeys;
    @ConstructorProperties({"rawMusic", "pianoKeys"})
    public Piano(Music music, String numberOfKeys) {
        this.rawMusic = music;
        this.numberOfKeys = numberOfKeys;
    }
    @Override
    public String toString() {
        return "Piano{" +
                "pianoMusic=" + rawMusic +
                ", numberOfKeys='" + numberOfKeys + '\'' +
                '}';
    }
}

Spring Configuration

  • Now we have the POJO's, now we are going to use the Configuration class to create these two bean objects:


@Configuration
@ComponentScan("springinjection")
public class MusicConfig {
    @Autowired Music rawMusic;
    @Autowired Music carnaticMusic;
    @Autowired Piano babyPianoMusic;
    @Autowired Piano pianoMusic;
    @Bean
    public String identifier(@Value("${genre:Generic}") String genre) {
        return genre;
    }
    @Bean(name = "rawMusic")
    @Value("#{genre}")
    public Music createMusic() {
        Music music = new Music();
        return music;
    }
    @Bean(name = "carnaticMusic")
    public Music createCarnaticMusic() {
        Music music = new Music();
        music.setGenre("Carnatic");
        return music;
    }
    @Bean(name = "pianoMusic")
    public Piano createPiano() {
        Piano piano = new Piano(rawMusic, "108");
        return piano;
    }
    @Bean(name = "babyPianoMusic")
    public Piano createBabyPiano() {
        Piano piano = new Piano(carnaticMusic, "88");
        return piano;
    }
}

String object in the Music class

The auto-wired genre property in the Music class is a bit tricky one to Initialize, spring by default treats auto-wired property as required. So when Music class is initialized the container will try to inject a value for the Genre property. But since there is no easy way to inject the String object, We are using the spEL. We will do more about the Spring EL in another post. Now that is all with our configuration file. we will use the following method expression:


@Bean
public String identifier(@Value("${genre:Generic}") String genre) {
        return genre;
}

AppRunner class

  • We will use AnnotationConfigApplicationContext API to inject and run the classes that we created. We will now look at the AppRunner class:

public class MusicRunner {
    public static void main(String args[]) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext("springinjection");
        Piano piano = applicationContext.getBean("pianoMusic", Piano.class);
        Piano babyPiano = applicationContext.getBean("babyPianoMusic", Piano.class);
        Music rawMusic = applicationContext.getBean("rawMusic", Music.class);
        System.out.println("Sathish Music :" + rawMusic);
        System.out.println("Grand Piano :" + piano);
        System.out.println("Baby Piano :" + babyPiano);
    }
}

We inform the container we are using the AnnotationConfigApplicationContext and specifying the package we are using. The other way to initialize the AnnotationConfig is using the class., for example:


ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MusicConfig.class);
        Piano piano = applicationContext.getBean("pianoMusic", Piano.class);
        
        

We have to make sure the MusicConfig class is annotated with @Configuration and the classes that it is annotating is preceding with @Component annotation. One other way to use the AnnotationConfig is to just call the default constructor and register the context at some later point. Let us take look at this sample:


AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.register(MusicConfig.class);
        ctx.refresh();
        Piano piano = applicationContext.getBean("pianoMusic", Piano.class);
        System.out.println("Sathish Music :" + rawMusic);
        
        

We will have to make sure we refresh the context after registering. The same came be done by passing a package as well. If we have an web application we can use the AnnotationConfigWebApplicationContext to configure.

Conclusion

We looked at how to use the AnnotationConfigApplicationContext to configure and run a spring application. With no XML code, spring now allows us to use annotations and configurations to build applications. Code for this sample can be found in github here

The sam berns parental advise.

I liked the quote about "Be OK with what you ultimately can't do, because there is so much that you can do." I don't think there is a better piece of logic for a parent to explaint to a child when he/she needs a motivation.

TreeMap's blast

Baby steps of util in the Java framework. This writeup is just a check point what I liked this week using these packages. Consider the case where you have to build out a fact tree where you will have to sort the students in your class based on their birth dates. Treemap gives a natural way of sorting based on date of birth. I liked the simplicity of the TreeMap.



package commons;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.Map;
import java.util.TreeMap;

public class TreeMapSample {
    public static void main(String args[]) {

        Kid kids[] = {new Kid("Kid1", DateTime.parse("05/01/05", DateTimeFormat.forPattern("MM/dd/yy")).toLocalDate()),
                new Kid("Kid2", DateTime.parse("01/06/05", DateTimeFormat.forPattern("MM/dd/yy")).toLocalDate()),
                        new Kid("Kid3", DateTime.parse("07/12/12", DateTimeFormat.forPattern("MM/dd/yy")). toLocalDate()) };
        Map sortedMap = new TreeMap();
        for (Kid kid : kids) {
            sortedMap.put(kid.getDob(),kid.getName());
        }
        System.out.println(sortedMap.values());

    }

    static class Kid {
        private String name;
        private LocalDate dob;

        public Kid(String name, LocalDate dob) {
            this.name = name;
            this.dob = dob;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public LocalDate getDob() {
            return dob;
        }

        public void setDob(LocalDate dob) {
            this.dob = dob;
        }
    }
}

Legacy systems and its issues. Equifax headache.

One of the most wretching thing for this year and weekend is Equifax issue. The follow up from the credit agency and its response to know whether you are affected or not is more frustrating. The protection that is offered for identity threat is 1 year. Heck, they already did an announcement almost after 6 weeks, and they can protect their customers only for 1 year. After that one has to pay $17 every month to be protected from this wretched organization. So from the initial reports, looks like they failed to upgrade their open source stack. The naked security explaination seems to be the best possible explaination how the struts framework was exploited.

I think this wrtie up from free code camp was much lighter read and was more informative.

My MooC concluded., it is the happiness course.

After almost so many years of trying and meddling., I was able to finish the first MooC Course from coursera. Here is the course I was able to finish A Life of Happiness and Fulfillment. It was 6 for weeks, good measured content and was very practical in the application part as well.

  • Week 1 starts about the shortcomings of happiness
  • Week 2 was about how to establishing a flow when doing work and daily tasks
  • Week 3 was about "creative alturism" it is very fancy way of saying give and do a lot charitable work.
  • Week 4 was about being overly controlling and how to go about getting some remedy for it.
  • Week 5 was "smart trust". I think this was very applicable for being a good team member and a life partner.
  • Week 6 was kind of a dud., but I think that is the solution for everything. This matched perfectly with OAK meditation app that am being a beta test user.

At last more self check points

My task manager has been reminding me for the past few days to write my blog post. But simply not following through, what I did in my focus course. But doing a self point check, Here is the another solution for freecodecamp challenge. The problem to solve is search and replace a specific string in an sentence. So the idea of the solution is get the input string, break into an array. Match the "before" parameter with one of the array element, if there is a match that is found then check for case sensitivity of the first character of the "before" parameter. If there is a match then change the "after" parameter to match the same case. Join all the array elements and return them.

function myReplace(str, before, after) {
 var arrayOfStrings =str.split(' ') ;
  for( var i=0;i<arrayOfStrings.length;i++){
    if(before===arrayOfStrings[i]){
      if(before.charAt(0)===before.charAt(0).toUpperCase()){
 after=after.replace(after.charAt(0),after.charAt(0).toUpperCase());
      }
      arrayOfStrings[i]=after;
    }
  }  
   return arrayOfStrings.join(' ');
 }

Few interesting things that caught my attention was couple of 60 minutes reports. If you have not watched the phone hooked episode, here is the link. The concept of brain hacking is very interesting. The other report that I thought was not reported well is the H1B visa abuse. I think H1B visa got popular and not take away jobs.

The stem was the Y2K bug, which demanded lot of software developers from India to finish the job to convert all the Y2K programs. You did not have to be thinking hard to convert those programs in a software developer world. It was more repetitive and someone who had knowledge how to do that repetitive job be able to do it. There was no need for much analytical and technical skill to get things done for resolving Y2K bug.

The employee from children hospital was very passionate about his users, I don't think there is any less compassion from a good programmer from any part of the world. The open source community thrives only because of developers who are passionate about making the world better. Continuing on that is when some of the firms got to see the software programmers from India and they simply got hooked to the model. The US consulate in my home town chennai knew there were only 4 firms that had a mainframe computer for training and it was impossible for those four firms to train and develop so many mainframe programmers. It had a blind eye giving out Visas for Y2K developers. The spigot got opened for the outsourcing firms at that point. I think the story was not retold properly to say how it started and how the big corporations evolved to latch onto the software engineers that they got during the Y2K boom and how that spilled into a boom where the outsourcing firms simply exploited it from then on. Software programmers from India were never intending to get the jobs from their peers as reported, they were shipped with all skills to meet the demand where body count was more important.

Finally the book of the season is Chaos monkey. I thorougly enjoyed the book and the bitching about the various silicon valley startups was really amazing. Check it out.

Articles and information week:

The Mythical 10x programmer.. This was a great writeup and I thoroughly enjoyed reading it as a developer. The discussion of 5% design will go a long way, is so true. I also liked the fact that it nailed some points like knowing data structures and C will help a long way. Talking about data structures, the interview article by programmers Omin from Nigeria was another interesting one.
The problem that I solved from free code camp was a good one. I know my solution was not efficient and elegant.

["diorite", "andesite", "grass", "dirt", "pink wool", "dead shrub"], ["diorite", "andesite", "grass", "dirt", "dead shrub"] should return ["pink wool"].

Solution

function diffArray(arr1, arr2) {
    var newArr = [];
    var arrHolder = [];
    var savedArr = [];
    var arr1Array = Array.prototype.slice.call(arr1);
    var arr2Array = Array.prototype.slice.call(arr2);
    var neverPopped = 0;
    if (arr1.length > arr2.length) {
        for (var i = 0; i < arr1Array.length; i++) {
            arrHolder.push(arr1Array[i]);
            if (arr2Array.indexOf(arr1Array[i]) >= 0) {
                arrHolder.pop();
                neverPopped++;
            }
        }
        for (var k1 = 0; k1 < arr2Array.length; k1++) {
            if (neverPopped === 0) {
                arrHolder.push(arr2Array[k1]);
            } else {
                if (arr2Array.indexOf(arrHolder[k1]) > 0) {
                    arrHolder.pop();
                }
            }
        }
        newArr = arrHolder;
    }
    if (arr2Array.length > arr1Array.length) {
        for (var j = 0; j < arr2Array.length; j++) {
            arrHolder.push(arr2Array[j]);
            if (arr1Array.indexOf(arr2Array[j]) >= 0) {
                arrHolder.pop();
            }
        }
        for (var k2 = 0; k2 < arr1Array.length; k2++) {
            if (arr1Array.indexOf(arrHolder[k2]) > 0) {
                arrHolder.pop();
            }
        }
        newArr = arrHolder;
    }
    if (arr2.length == arr1.length) {
        for (var k = 0; k < arr2Array.length; k++) {
            arrHolder.push(arr2Array[k]);
            if (arr1Array.indexOf(arr2Array[k]) >= 0) {
                arrHolder.pop();
            }
        }
        for (var k4 = 0; k4 < arr1Array.length; k4++) {
            arrHolder.push(arr1Array[k4]);
            if (arr2Array.indexOf(arr1Array[k4]) >= 0) {
                arrHolder.pop();
            }
        }
        newArr = arrHolder;
    }
    console.log(newArr);
    return newArr;
}

Hidden figures is an amazing read. I do not know much about this Susan fowler write-up but it was viral and definetly not the one that I expected to read after the book. Finally Saturday was #FakeNews day with wiretaps. But there was a theory for the president's tweets, here is a related opinion.