Thursday, 4 February 2016

Android Booting process

Background

Android as we know uses a Linux kernel underneath and as all operating systems it has a boot sequence. Android has following stack -


You can see complete details in one of my previous posts - 

In this process we will see how booting happens in Android.


Android Boot Sequence

To represent the entire process in a picture it would be something like below - 



  1. When you power on your Android device Boot ROM which is hardwired code at a predefine location in your ROM starts executing. This loads your Bootloader code in your RAM and starts executing.
  2. Bootloader is a process that starts before Android OS is loaded. Bootloader code itself is not a part of Android operating system. This code will be customized by the OEMs to put in their restrictions. This program sets up necessary things to run the kernel like memory, clock, network etc.
  3. Next kernel is launched. As the kernel launches, is starts to setup cache, protected memory, scheduling and loads drivers. System can now use virtual memory and launch user space processed. When the kernel finishes the system setup , it looks for “init” in the system files and launch it as the initial user space process.
  4.  init process is the parent process of all processed. This can be found at location  -
    • <android source>/system/core/init
    It is the 1st user process that starts. It has two resposibilities -.
    1. Mounts directories like /sys , /dev or /proc and
    2. Runs init.rc file located at - <android source>/system/core/rootdir/init.rc
    This is a script that describes the system services, file system and other parameters that need to be set up. If you refer above picture init process initializes zygote, runtime and daemon processed. At this point you should see the Android logo on your screen. 
  5. As we know each Java process runs in a separate JVM. However in an handheld system like that of Android both memory footprint and startup time must be considered. So JVM with some customizations needed for Android is called Dalvik VM that runs Android applications.  Also initi process which starts up Zygote process preloads and initializes core libraries needed for the VM. For each new app a new VM is forked from zygote and app is run in it's sandboxed environment. Zygote provides pre warmed up VM instance to the app to run thereby reducing the startup time.
  6. After complete above steps, runtime request Zygote to launch system servers. System Servers are written in native and java both. The system server is the first java component to run in the system. It will start system services like Power Manager, Activity Manger, Telephony Service etc.
  7. Once System Services up and running in memory, Android has completed booting process, At this time “ACTION_BOOT_COMPLETED” standard broadcast action will fire.
 When an app starts new VM is forked from zygote and app is started in it (sanboxed).



NOTE : When zygote does a fork on receiving a command it uses copy-on-write technique. Memory is copied only when the new process tries to modify it.

Also the core libraries that zygote loads on startup are read only and cannot be modified. So they are not copied over but shared with new forked processes.

All of these led to quick startup and less memory footprint.

NOTE : Zygote isn't really bound up with Dalvik, it's just an init process. Zygote is the method Android uses to start apps. Rather than having to start each new process from scratch, loading the whole system and the Android framework afresh each time you want to start an app, it does that process once, and then stops at that point, before Zygote has done anything app-specific. Then, when you want to start an app, the Zygote process forks, and the child process continues where it left off, loading the app itself into the VM.

Related Links

Monday, 25 January 2016

Replacing web.xml with Java based configuration for Servlet 3.x Webapplications using Spring

Background



As we know if you want to deploy a web app in a container like tomcat you have a context file called web.xml that creates context necessary for you app to run. For eg. you can provide libraries that will be available to your web app. 

Your typical web.xml will look like - 


<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <display-name>Spring Web MVC Demo Application</display-name>

  <servlet>
      <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
     <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
  </servlet-mapping>
   

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

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


Lets see its Java equivalent

Java Configuration

  • For Java configuration you can write your own class that implements WebApplicationInitializer  interface and override it's
    onStartup() method.
  • WebApplicationInitializer is an interface provided by Spring MVC that ensures your implementation is detected and automatically used to initialize any Servlet 3 container.
  • An abstract base class implementation of WebApplicationInitializer named AbstractDispatcherServletInitializer makes it even easier to register the DispatcherServlet by simply overriding methods to specify the servlet mapping and the location of the DispatcherServlet configuration.  
  • This is from Spring 3.1+
Lets now see the Java config -


public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
    
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

        rootContext.register(RootApplicationConfig.class);
       
        container.addListener(new ContextLoaderListener(rootContext));
       
        AnnotationConfigWebApplicationContext displacherContext = new AnnotationConfigWebApplicationContext();
        displacherContext.register(MyWebConfig.class);
    
    
        ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(displacherContext));
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
} 


Or as I mentioned before you can extend abstract class AbstractDispatcherServletInitializer.

public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }

    @Override
    protected WebApplicationContext createServletApplicationContext() {
        XmlWebApplicationContext cxt = new XmlWebApplicationContext();
        cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
        return cxt;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }


Now you don't need web.xml as part of your web application. Your container will startup your app using Java config provided. This classes are detected automatically.

If you are not using Spring you will need to do -

  1. Create a custom class that implements ServletContainerInitializer (i.e. com.osfg.MyServletContainer
  2. Create a file in your META-INF/services folder named javax.servlet.ServletContainerInitializer which will contain the name of your implementation above (com.osfg.MyServletContainer)
In Spring ofcourse you don't need to do this.

Related Links

Friday, 8 January 2016

Making @PathVariable optional in Spring MVC

Background



A simple controller class would look like - 


    @RequestMapping(value="/home/{name}", method = RequestMethod.GET)
    public String welcome(Model model,  @PathVariable(value="name") String name, @RequestParam(value="surname") String surname) {
        model.addAttribute("test", "TestValue");
        System.out.println("Name : " + name);
        System.out.println("Surname : " + surname);
        return "welcome";
    }

This controller method basically expects a URL like 
  • http://localhost:8080/WebProject/home/aniket?surname=thakur
where aniket is the name (path variable) where as thakur is the surname (request param).

Here you cannot have name or surname blank. If you do you will get an error.  So URLs like -
  • http://localhost:8080/WebProject/home?surname=thakur OR

    You will get  HTTP Status 404 - Requested Resource is not available
  • http://localhost:8080/WebProject/home/aniket

    You will get - HTTP Status 400 - Required String parameter 'surname' is not present
 will not work!

 Only URL that will work as mentioned above is -

  • http://localhost:8080/WebProject/home/aniket?surname=thakur
For this URL you should see output as -

Name : aniket
Surname : thakur

However you can make @RequestParam option. Spring provides you this functionality. All you have to do is set it's required property as false i.e
  • @RequestParam(value="surname", required=false) String surname
Now you can hit the URL -
  •  http://localhost:8080/WebProject/home/aniket
and you should not see 404 error. Output would print -

Name : aniket
Surname : null

However there is no such parameter in @PathVariable. So you cannot truly make it optional. However there are alternative and we will look at them now.

 Making @PathVariable optional in Spring MVC

There are two way in which you can work - 

  1. Provide two paths in value - One with path param and one without. In Arguments take map of path params and check for null.


        @RequestMapping(value={"/home/{name}","/home"}, method = RequestMethod.GET)
        public String welcome(@PathVariable Map<String, String> pathVariablesMap) {
            if (pathVariablesMap.containsKey("name")) {
                //corresponds to path "/home/{name}"
                System.out.println("With Name : " + pathVariablesMap.get("name"));
            } else {
                //corresponds to path "/home"
                System.out.println("With No Name");
            }   
            return "welcome";
        }
    


    Here you are essentially saying this controller will map to both URLS - "/home/{name}" and "/home" and if you do get name in pathparams map then the URL was "/home/{name}" else it was "/home".

    And now if you hit http://localhost:8080/WebProject/home/aniket you should get output as - "With Name : aniket" and if you hit http://localhost:8080/WebProject/home you should see output - "With No Name".
  2.  Another way is to use java.util.Optional provided by Java8. So if you are using Spring 4.1 and Java 8 you can use java.util.Optional which is supported in @RequestParam, @PathVariable, @RequestHeader and @MatrixVariable in Spring MVC -

        @RequestMapping(value="/home/{name}", method = RequestMethod.GET)
        public String welcome(@PathVariable Optional<String> name) {
            if (name.get() != null) {
                //corresponds to path "/home/{name}"
                System.out.println("With Name : " + name.get());
            } else {
                //corresponds to path "/home"
                System.out.println("With No Name");
            }   
            return "welcome";
        }
    


    Repeat same test as point 1. You should get same result. This is just another alternate way.

So as we have seen pathvariables cannot truly be null but there are workarounds. This case should not typically arise as it is poor design. You should always have some value in path param. If you are certain it can be null better make it a @RequestPram and use requiref=false.


Related Links

Sunday, 3 January 2016

Using @ModelAttribute annotation in Spring MVC

Background

There are many cases in which you may need to populate your Model with some default data or bind the data in request in your model in controller/handler method. It are these cases when @ModelAttribute annotation comes in handy. So in this post we will see how exactly @ModelAttribute method works with some example.



Working of @ModelAttribute

  • Before starting I would like to assert your class should be a controller class for this to work which means your class should be annotated with @Controller annotation .
Next this  @ModelAttribute can be at
  1. Method level OR
  2. Method argument level.

We will come to each in a moment.  @ModelAttribute take an optional "value" that represents the name of this attribute. For eg. @ModelAttribute("test") Why we say it is optional? Because as per Springs "Convention over Configuration" principle it allows you to not to provide explicit value and in which case default name is assigned to the ModelAttribute. For eg. if you have a class called "Car" then the model attribute will be stored in the Model by name "car" (notice the small letter c).

The way this annotation works is as follows -

  1. Before invoking the handler method, Spring invokes all the methods that have @ModelAttribute annotation. So yeah a Controller annotated class can have multiple @ModelAttribute annotated methods. It adds the data returned by these methods to a temporary Map object. The data from this Map would be added to the final Model after the execution of the handler method.
  2. Then it prepares to invoke the the handler method. To invoke this method, it has to resolve the arguments. If the method has a parameter with @ModelAttribute, then it would search in the temporary Map object with the value of @ModelAttribute. If it finds, then the value from the Map is used for the handler method parameter.
  3. If it doesn't find it in the Map, then it checks if there is a SessionAttributes annotation applied on the controller with the given value. If the annotation is present, then the object is retrieved from the session and used for the handler method parameter. If the session doesn't contain the object despite of the @SessionAttributes, then an error is raised.
  4. If the object is not resolved through Map or @SessionAttribute, then it creates an instance of the parameter-type and passes it as the handler method parameter. Therefore, for it to create the instance, the parameter type should be a concrete-class-type (interfaces or abstract class types would again raise an error).
  5. Once the handler is executed, the parameters marked with @ModelAttributes are added to the Model.

Above is the general working of the annotation at method level or method argument level.


Styles for using ModelAttribute

You can use one of the following styles for adding ModelAttributes to Model - 

  1. Implicitly return variables which will get added to the Model


    @ModelAttribute("data")
    public String addData() {
        return "test";
    }
    

    NOTE : Above "test" String will be added to the Model as name "string"(small s) i.e string=test. If you do something like below -

    @ModelAttribute
        public List<String> addTest() {
            return Arrays.asList("newValue");
        }
    


    then name will be "stringList" i.e stringList=[newValue].
  2. OR get the Model object and explicitly add multiple data to it

    @ModelAttribute
    public void addData(Model model) {
        model.addAttribute("test");
        model.addAttribute("tes1");
        // add more ...
    }
    



    NOTE : If you add in model two attributes with same name the later one will override the 1st one. Consequently in above code "test1" will override "test" as value for name "string" which is constructed with convention i.e string=test1(After all it is a Map underneath and keys of Map are unique (if you remember keys returns set data structure)).

Examples

Now let us see examples that will help us understand above concepts even more.

Following is a simple Controller class - 

@Controller
public class WelcomeController {

    @RequestMapping(value="/home", method = RequestMethod.GET)
    public String welcome() {
        return "welcome";
    }
    
    @ModelAttribute("test")
    public String addTest() {
        return "testValue";
    }
    
}

Here is what is happening -  As we know before handler methods are executed all methods annotated with @ModelAttribute are execute. Consequently out addTest() method gets executed and adds a String with name "test" in the Model. You can access the same in your JSP called "welcome.jsp" as follows - 

  • <h1><c:out value='${test}' /></h1>
and here you will see  "testValue" is h1 heading size.

You can also access this ModelAttribute in your handler method as follows -

    @RequestMapping(value="/home", method = RequestMethod.GET)
    public String welcome(@ModelAttribute("test") String test) {
        System.out.println(test);
        return "welcome";
    }


and you should see "testValue" getting printed in your server console. You can even override the value of "test" ModelAttribute in your handler class.

    @RequestMapping(value="/home", method = RequestMethod.GET)
    public String welcome(@ModelAttribute("test") String test, Model model) {
        System.out.println(test);
        model.addAttribute("test", "newTestValue");
        return "welcome";
    }


and now your JSP should show "newTestValue" in h1 heading.

NOTE: When using controller interfaces (e.g. for AOP proxying), make sure to consistently put all your mapping annotations — such as @RequestMapping and @SessionAttributes — on the controller interface rather than on the implementation class.

NOTE : SessionStatus.setComplete() method will trigger cleaning of Session Attributes, but only those which Spring will find "actual session attribute". Suppose that you declare 3 session attributes, but use only 1 of them in your handler method parameters then only that will be cleared.

Related Links

Friday, 1 January 2016

Using interceptors in Spring MVC

Background

Interceptors as their name suggest intercepts request that are delegated to your controller by the dispacher setvlet. Why would we do that you ask? Well there are multiple possibilities. You can implement in these interceptors functionality that is common to multiple controllers. Like for eg - 
  • Add common model attributes
  • Set response header
  • Audit requests
  • Measure performance etc
In this post we will see how to implement those interceptors in Spring MVC.


HandlerInterceptor interface

HandlerIntercetor is an interface with following methods - 

  • boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler);
  • void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler. ModelAndView modelAndView);
  • void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler. Exception ex);
Their call sequence is reflected in following picture -




NOTE : 

preHandle() returns either true or false -
  • true : continue doewn the interceptor chain
  • false : invoke controller and skip remaining interceptors
Does this also mean you can have multiple interceptors? Precisely Yes! You can chain interceptors and they will be called one after another.

As in most case you don't want to implement all 3 methods so Spring has a separate class called - HandlerInterceptorAdapter which you can easily extend and override those methods that you need.


Configuring Interceptors

- Always keep in mind interceptors are are HandlerMapping level!

Spring as you know has multiple components like
  • HandlerMapping
  • HandlerAdapter
  • ViewResolver
  • HandlerExceptionResolver
 and user define components like
  • Controllers/Handler
  • Interceptors
There are 3 ways to configure interceptors

  1. Define interceptor as a property of your HandlerMapping bean -

    <bean class="...DefaultAnnotationHandlerMapping">
        <preoperty name="interceptors">
            <list>
                <bean class=""/>
                <bean class=""/>
            </list>
        </property>
    </bean>
  2. OR use mvc namespace to define interceptors -

    <mvc:interceptors>
        <bean class="myPackage.Interceptor1"/>
        <bean class="myPackage.Interceptor2"/>
    </mvc:interceptors>

    NOTE : This will be applied to all HandlerMapping beans. If you want to restrict your interceptors to particular HandlerMapping use -
  3. mapping paramter. You can optionally give exclude paramter too (available from Spring 3.1+)
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/secure/*" />
            <mvc:exclude-mapping path="/secure/help" /> 
            <bean class="" />
        </mvc:interceptor>
    </mvc:interceptors>

Interceptor Example

Lets see an example of how to create an interceptor - 

Lets first create s simple servlet configuration to configure our dispacher Servlet - 

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

  <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>/admin/*</url-pattern>
  </servlet-mapping>

</web-app>

As you can see our dispacher servlet will server all requests that are of format 
  • http://localhost:8080/projectName/admin
 projectName is the name of Spring project you have provided.


Now lets create the Spring configuration. Create a file under /WEB-INF/spring with xml extension and add following contents to it -

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/mvc 
                        http://www.springframework.org/schema/mvc/spring-mvc.xsd
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context.xsd">


    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <context:component-scan base-package="myPackage" />

    <mvc:annotation-driven/>

     
    <mvc:interceptors>
            <bean class="myPackage.TestInterceptor" />
    </mvc:interceptors>     
    

</beans>


If you notice we have configured an interceptor to intercept all requests (i.e applicable for all handler mappings)

If you want it to be for specific URL you can do something like - 

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="myPackage.TestInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors> 

or

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/home" />
            <bean class="myPackage.TestInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors> 


Finally lets create our Controller and interceptor -

WelcomeController.java

@Controller

public class WelcomeController {
    @RequestMapping(value="/home", method = RequestMethod.GET)
    public String welcome() {
        return "welcome";
    }
}    

and TestInterceptor.java

public class TestInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Request intercepted");
        return true;
    }
    
}

After you have done this setup you can hit -
  • http://localhost:8080/projectName/admin/home
and see  "Request intercepted" printed in the logs. Also you can define multiple such <mvc:interceptor> tags thereby chaining them.

Also not interceptors will be hit only if the path that you are hitting is valid. Si if you try /home/test then interceptor will not be hit. It will be hit only if the requested path forms a part of valid HandlerMapping (like /home in above case).

Also will remind you again interceptors are configured at HandlerMapping level. In this case it would be RequestMappingHandlerMapping (Spring 3.1+ with mvc:annotation-driven) or DefaultAnnotationHandlerMapping.


Related Links

t> UA-39527780-1 back to top