Sunday, 27 September 2015

Context loading in Spring MVC

Background

Spring need no introduction. It is a well know Java framework that use DI (dependency Injection) or Ioc (Inversion of control). I have previously written couple of posts on Spring which you can read in the Related Links section at the bottom of this post. In this post I am specifically going to write about Spring context and how is it loaded.

Context loading in Spring MVC

We generally load spring context in deployment descriptor file called web.xml that is generally located under WEB-INF directory of the projects war file. There are two ways the context can be loaded

  1. You can load the context using ApplicationContext in which case the loaded context will be accessible to entire Application (including various configured endpoints like Dispacher Servlet, Webservice Servlet, REST servlet etc). OR
  2. you can load the context that is specific to an entry point (WebApplicationContext). For example loading context just for Dispacher Servlet. OR
  3.  Use combination of both. Use Application context to load your backend service, access or repository beans that will be used by entire application and your controller, view resolver beans in WEbApplicationContext.



Lets see each in detail

Application  Context

You can do this like follows - 

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>

<listener>
   <listener-class>
        org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener> 


  • Default name of this file is applicationContext.xml. If you do not provide application context configuration file in web.xml using contextConfigLocation as mentioned in config above then file named applicationContext.xml is searched in under WEB-INF folder.
  • There can be only one application context per web application.

WebApplicationContext

You can do that as follows - 
  <servlet>
    <servlet-name>admin</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
                /WEB-INF/spring/*.xml
            </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>


  <servlet-mapping>
    <servlet-name>admin</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  • Default name of this file is xxx-servlet.xml where xxx is the DispatcherServlet name in web.xml
  • A web application can have multiple Dispacher servlets and thereby have multiple such webapplication contexts.




Note 
  1. Application Context is parent context of each WebApplication Contexts.
  2. If a bean is not found in a particular wevbapplication context it is then searched in the parent application context.
  3. Application context is basically to initialize beans that are singleton in nature and can be used throughout the application like your data access bean or your service beans.


Related Links

Saturday, 26 September 2015

Deleting a project from Chrome Rest client

Background

Making REST API calls from some client to test out stuff is normal for any programmer. Programmers use various REST clients. I have seen most of the programmer use either
  1.  Postman or
  2.  Advanced REST client.
I prefer the  later one. No particular reasons but I just started with Advanced REST client so continuing with the same.




So in Advanced REST client you can save your REST calls in a PROJECT. A project can have multiple REST calls associated with it. This is where I was stuck. I created multiple projects with some dups and wanted to clean it up. Advanced REST client allows you to delete the API calls from the project but not the project itself. So naturally you looks for workarounds and today I will show you one.

Solution is quite simple. You delete it yourself from the application database. All you need to know is where and how. We will see that now.


 Deleting a project from Chrome Rest client

I have created a dummy project named GREETINGS and have added a dummy API call called ADD_CUST. Deleting API call is easy. Just click the delete icon just besides the API selector on the top.




As you must have notices we do not have option to delete project itself. Lets see how we can do that by deleting project from App database. Follow below steps

  1. Right click 
  2. Inspect Element 
  3. Go to resources Tab
  4. Select restClient DB
  5. view projects table

You will see all the projects listed there.



Notice the ID of the project here. it's 10. We will use it later.  For now lets just see how can we run SQLs here. For this click on the database -restClient in this case. You should see a prompt. You can enter your SQL queries here.

Run simple query :
  • select * from projects;
You should see list of all available projects.



 Finally lets see how we can delete a project. Execute following query.

  • delete from projects where id=10;
Your project should get deleted from the DB. You can verify it by running select again.



Now simply refresh the page and you should see your project gone!

 

SOAP vs REST Web Services

Background

        It's been around couple of months since this topic has confused me a lot. Every time I have discussion about webservices I always try to figure out difference between SOAP based web service (JAX-WS Java API) and REST based web service (JAX-RS) web service. When the picture is finally clear let me put it down for others.

Biggest point to note about SOAP and REST is that they cannot be compared!  Yes you read it right you cannot compare both. You can only do comparison of things that are different aspects of same thing and these are not. 

SOAP (Simple Object Access Protocol) is a protocol which uses XML to communicate data. Like any other protocol it has it's own rules. REST (Representational State transfer) on the other hand is an architecture (repeating architecture) meaning a way to design APIs. 

Given that we will see each in a bit more detail so that it gives us a clear picture of REST and SOAP based web service.

W3C defines a web service as
 "A software system designed to support interoperable machine-to-machine interaction over a network."

SOAP based web services

  • SOAP stands for Simple Object access protocol.
  • As the name suggests this is a protocol. 
  • SOAP uses service interfaces and named operations to expose the APIS.
  • SOAP requires more bandwidth that REST requests.
  • You can only transfer (send/receive) XML payload from SOAP based webservices.
  • Java API for this is JAX-WS
  • SOAP has Web Services Description Language (WSDL) which describes how webservice will work and lets you get a reference to it.
  • SOAP based messages have strict specifications to follow for implementation.
  • SOAP defines it's own security standards WS-security..


REST based web services

  • REST stands for Representational state transfer.
  • This is an architectural approach.
  • REST uses URLs and method types (HTTP verbs like GET, POST, PUT etc) to expose APIs.
  • REST requires less bandwidth that SOAP based requests.
  • In REST you can send and receive any type of payload (Json, XML, HTML).
  • Java API for this is JAX-RS
  • REST does not have strict restrictions like SOAP.
  • For security REST calls rely in underlying protocol like HTTPS.


Generic Notes

  1. HTTP verbs used by REST
    1. GET
    2. OPTION
    3. POST
    4. PUT
    5. PATCH
    6. DELETE
  2. Careful with HTTP POST verb. It is not safe and not idempotent.So You cannot just resend.
  3. In REST based requests , response may be cached. Server may return ETag header when accessed. Client send this tag on subsequent request to access resource. If resource is not changed server will return 304 (not modified).




Major differences between GET and POST

 

Related Links 


 

Saturday, 12 September 2015

Find the row with maximum number of 1s

Background

This is a data structure and an interview question. It goes as follows - 

"Given a boolean 2D array, where each row is sorted. Find the row with the maximum number of 1s."

or to put it another way each row will have either all 0's or all 1's or k 0's and (n-l) 1's given a 2D array of m*n. Also each k 0's are contiguous and same goes with (n-1) 1's. In short they are sorted. This is just to confuse the interviewee and do not give straight hint that we are dealing with sorted things here :)

Example is in screenshot below-


Note : This question is also in GeeksForGeeks site which has solution in C. I am just going to provide solution in Java. So lets get started.


Brute Force

Brute force is the worst complexity approach you can take. It gives solution... just not in efficient way. I believe you should always start with this approach. This helps  you get a better hang of the problem and interviewer will know you can get things done. Efficiency is something you can always work on or get help of colleges or code reviewers (it will comes more fluently with experience). So always start with brute force approach. 

For this brute force approach would be to iterate over all columns in each row and keep a count of maximum no of 1's in each row and index of that row. Finally return it when you are done with the looping. Time complexity for this would be O(m*n) for a 2D array of dimension m*n. So lets see how this would go.

/**
 * @author athakur
 * Brute force approach
 */
public class BruteForce {
    
    public int compute(int[][] array) 
    {
        int maxRowOnesIndex = 0;
        int maxRowOnesCount = 0;
        for(int i=0;i<array.length;i++)
        {
            int localMaxOnesCount = 0;
            for(int j=0; j<array[i].length;j++)
            {
                if(array[i][j] == 1) {
                    localMaxOnesCount++;
                }
            }
            if(localMaxOnesCount > maxRowOnesCount)
            {
                maxRowOnesCount = localMaxOnesCount;
                maxRowOnesIndex = i;
            }
        }
        return maxRowOnesIndex;
    }
}

To use this methods class and test the working execute following code.

 /**
 * @author athakur
 * Starter code for computing row with maximum 1's in a 2D array
 */
public class Compute {
    public static void main(String args[])
    {
        int[][] array = new int[][]{{0,1,1,1},{0,0,1,1},{1,1,1,1},{0,0,0,0}};
        System.out.println(new BruteForce().compute(array));
    }
}



Output : 2

That's the brute force method. As mentioned earlier it's time complexity is O(m*n) which is like the worst complexity. Can we do better than this? Sure we can :)

What is it that we can leverage here? We know that each row in the 2D array is sorted. We can easily to a binary search to find the leftmost 1. Count of 1st will be no of columns minus index of leftmost one. Now guess what the time complexity is for this approach?

It is O(m*logn). We iterate over each row (total of m rows) and then do a binary search on each row with log n complexity.

/**
 * @author athakur
 * Binary Search approach
 */
public class BinarySearch {

    private int first(int[] array, int low, int high)
    {
        if(high >= low)
        {
            int mid = low + (high-low)/2;
            if((mid == 0 || array[mid-1]==0) && (array[mid] == 1))
            {
                return mid;
            }
            else if(array[mid] == 0) {
                return first(array, mid + 1, high);
            }
            else {
                return first(array, low, mid-1);
            }
        }
        return -1;
    }
   
    public int compute(int [][] array)
    {
        int maxRowOnesIndex = 0;
        int maxRowOnesCount = 0;
        
        for(int i=0; i< array.length;i++)
        {
            int onesIndex = first(array[i], 0, array[i].length-1);
            if(onesIndex != -1)
            {
                int localMaxOnesCount = array.length - onesIndex;
                if(localMaxOnesCount > maxRowOnesCount)
                {
                    maxRowOnesCount = localMaxOnesCount;
                    maxRowOnesIndex = i;
                }
            }
        }
        return maxRowOnesIndex;
    }
    
}



And run it with


/**
 * @author athakur
 * Starter code for computing row with maximum 1's in a 2D array
 */
public class Compute {
    public static void main(String args[])
    {
        int[][] array = new int[][]{{0,1,1,1},{0,0,1,1},{1,1,1,1},{0,0,0,0}};
        System.out.println(new BinarySearch().compute(array));
    }
}


Output :2

Note : The above solution can be optimized further. Instead of doing binary search in every row, we first check whether the row has more 1s than max so far. If the row has more 1s, then only count 1s in the row. Also, to count 1s in a row, we don’t do binary search in complete row, we do search in before the index of last max.

So basically lets say 1st row has m 1's we will check for each for the subsequent row i whether array[i][n-m-1] is 1.

Related Links

Thursday, 3 September 2015

Installing Oracle instant database client in Ubuntu

Background

In this post I am going to show how to install oracle instant client (database client) on your ubuntu machine. After this you should be able to connect to your oracle server and execute queries on it from your machine using sqlplus.

Prerequisites

 Firstly find out whether your system is 32 bit or 64 bit. Easiest way to find out is to execute
  • uname - a
If your machine is 64 bit you should notice something like x64 in the output. If you don't see it 32 bit like in my case (refer screenshot below)



Next make sure you have alien command installed. We will need to to convert rpm packages to deb. To install simply run
  • sudo apt-get install alien 


 Installing Oracle instant database client

  1. Download instant client files from oracle site.Select correct files depending on your operating system and architecture. For me it is Ubuntu and 32 bit. So I have downloaded following files
    1. oracle-instantclient12.1-basic-12.1.0.2.0-1.i386.rpm
    2. oracle-instantclient12.1-sqlplus-12.1.0.2.0-1.i386.rpm
    3. oracle-instantclient12.1-devel-12.1.0.2.0-1.i386.rpm
  2. Since only rpm files are available and Ubuntu works with debian we need to convert rpm packages to deb packages.
    1. alien -k  oracle-instantclient12.1-basic-12.1.0.2.0-1.i386.rpm
    2. alien -k oracle-instantclient12.1-sqlplus-12.1.0.2.0-1.i386.rpm
    3. alien -k oracle-instantclient12.1-devel-12.1.0.2.0-1.i386.rpm
  3. Now to install .deb packages use dpkg -i packageName
    1. dpkg -i oracle-instantclient12.1-basic-12.1.0.2.0-1.i386
    2. dpkg -i oracle-instantclient12.1-sqlplus-12.1.0.2.0-1.i386.rpm
    3. dpkg -i oracle-instantclient12.1-devel-12.1.0.2.0-1.i386.rpm  
  4. Now you need to set some environment variables. Open ~/.bashrc file and add export following environment variables (add following line to file)
    1. export ORACLE_HOME=/usr/lib/oracle/12.1/client
    2. export LD_LIBRARY_PATH=/usr/lib/oracle/12.1/client/lib/
    3. export PATH=$PATH:$ORACLE_HOME/bin
  5. To make source your changes are reflected in same terminal execute
    1. source ~/.bashrc
And  you should be good to go. Verify your env variables.



Resolving errors

sometimes you may get following error

"sqlplus: error while loading shared libraries: libsqlplus.so: cannot open shared object file: No such file or directory"



in this case double check you have added LD_LIBRARY_PATH environment variable and it is pointing to write directory. Quick way to check is 
  • echo $LD_LIBRARY_PATH
  • cd <output_of_above_command>
Sqlplus should now be recognized and work as expected


If you see errors related to libaio.so.1 missing then install it using
  • sudo apt-get install libaio1

Related Links


t> UA-39527780-1 back to top