SpringBoot With Angular 4 Integration and Social Authentication

As a full stack developer, we need to create an application with both frontend-end and backend.

Today we will create a simple full stack application which will have a social login using Google authentication.The area on which we want to focus is how to integrate google social authentication to spring-boot, with logout functionality. And when angular 4 is used in spring-boot application to build the UI, how we will manage the routes, as we know that both angular and have routes, so how our application will resolve which route it has to call.

Tech Stack

  • Angular 4
  • SpringBoot
  • Gradle

Prerequisites

Let’s start creating an application

  • Create a simple spring boot application using Spring.io
    • Project Type with gradle and Java
    • Add necessary description, group, and artifact
    • Add following dependencies to it.

compile 'org.springframework.cloud:spring-cloud-starter-config'
compile('org.springframework.boot:spring-boot-starter-web')
compile("org.springframework.boot:spring-boot-starter-tomcat")
compile 'org.springframework.security:spring-security-web'
compile 'org.springframework.security:spring-security-config'
compile 'org.springframework.security.oauth:spring-security-oauth2'
compile 'org.apache.httpcomponents:httpclient'
compile("io.springfox:springfox-swagger2:2.6.1")
compile("io.springfox:springfox-swagger-ui:2.6.1")

testCompile('org.springframework.boot:spring-boot-starter-test')
compile group: 'org.slf4j' , name: 'slf4j-api' , version: '1.7.22'
compile group: 'io.jsonwebtoken' , name: 'jjwt' , version: '0.7.0'
compile group: 'commons-io' , name: 'commons-io', version: '2.5'
compile group: 'org.projectlombok' , name: 'lombok' , version: '1.16.12'

These dependencies will allow us to enable the google authentication on the top of normal spring boot application.

  • Create the property file application-local.yml in the java main resources.

security:
oauth2:
client:
clientId: ******.apps.googleusercontent.com
clientSecret: ********
accessTokenUri: https://www.googleapis.com/oauth2/v4/token
userAuthorizationUri: https://accounts.google.com/o/oauth2/v2/auth
clientAuthenticationScheme: form
scope:
- openid
- email
- profile
resource:
userInfoUri: https://www.googleapis.com/oauth2/v3/userinfo
preferTokenInfo: true

user:
role: test-role

We have created a property file to enable google authentication against the particular client.Replace the * with your actual data.

  • Create bootstrap.yml with following data.
<pre>spring:
  application:
    name: frontend
  profiles:
    active: local
  cloud:
    config:
      uri: http://localhost:8888
      enabled: true</pre>

It will help us to give the name to our application and will activate “LOCAL” profile.

  • Create a Security Config java file “SpringConfig” on the same level as of the main file.

package com.test.practise;

import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableOAuth2Sso
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers( "/login","/public/**", "/resources/**","/resources/public/**")
                    .permitAll()
                .antMatchers("/","/api/**").authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login")
                .defaultSuccessUrl("/");
    }
}

It will apply authentication to all the path accept /login,  /public,  /resources/public/.

  • Add controller for logout “SecurityController”
<pre>package com.test.practise.controller;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class SecurityController {


    @RequestMapping(value="/logout", method = RequestMethod.GET)
    public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null){
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return "redirect:/";
    }
}
</pre>

It will enable the logout URL, which will delete the session.

  • We are not pretty much done with the spring side coding, but we have not added any view or frontend related code yet. We will create the angular project now.
  • Go to the root of the project and create the angular project angular-cli.

ng new webui

It will create a new project directory for frontend inside our current project directory.

  • Navigate to a webui directory which you have created, and make 3 testing controller using the following command.

ng g component landingComponent

ng g component homeComponent

ng g component settingComponent

These are the dummy component to show the routing.

  • Now we will mention our routes in the angular project in file app.module.ts

<pre>import {RouterModule, Routes} from "@angular/router";</pre>


const appRoutes: Routes =[

{path:'',component:LandingComponent},
{path:'welcome',component:WelcomeComponent},
{path:'setting',component:SettingComponent}

]

 

 

  • Add routing module in Imports in the same file.
<pre>@NgModule({
  declarations: [
    AppComponent,
    WelcomeComponent,
    SettingComponent,
    LandingComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(appRoutes,{enableTracing:true})
  ],
  providers: [],
  bootstrap: [AppComponent]
})

</pre>
  • replace the code of app.component.html the main page of ui with following code.

<pre>&lt;!–The content below is only a placeholder and can be replaced.–&gt;
&lt;div style="text-align:center"&gt;
&lt;h1&gt;
Welcome to {{title}}!!
&lt;/h1&gt;
&lt;img width="300" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo="&gt;
&lt;/div&gt;
&lt;a href="/setting"&gt;Direct Setting&lt;/a&gt;
&lt;a href="/welcome"&gt;Direct Welcome&lt;/a&gt;
&lt;nav&gt;
&lt;a routerLink="/" routerLinkActive="active"&gt;Landing Page&lt;/a&gt;
&lt;a routerLink="/welcome" routerLinkActive="active"&gt;Welcome Page&lt;/a&gt;
&lt;a routerLink="/setting" routerLinkActive="active"&gt;Setting Page&lt;/a&gt;
&lt;/nav&gt;
&lt;router-outlet&gt;&lt;/router-outlet&gt;

</pre>

It will create the routes .First two route for setting and welcome is using href. normal HTML routes and then we have refined routes using routerLink.

  • Build the frontend application

ng build

  • Now we will make changes in spring application to consume this frontend code.First of all, we will add the  code in our build.gradle to copy the frontend code and place it in resource so that it can be consume by spring-boot.
  • Add following task to build.gradle

<pre>

task removeWebui(type: Delete) {
delete "${sourceSets.main.resources.srcDirs[0]}/webui"
}

task copyWebui(type: Copy) {
from "webui/dist"

into "${sourceSets.main.resources.srcDirs[0]}/webui"
exclude "*.gz"
//eachFile { println it.name }
}

task downloadRedoc(type: Download) {
src "https://rebilly.github.io/ReDoc/releases/latest/redoc.min.js&quot;
dest "${sourceSets.main.resources.srcDirs[0]}/public/redoc"
overwrite true
}

task var &lt;&lt; {
sourceSets {
main {
println "java.srcDirs = ${java.srcDirs}"
println "resources.srcDirs = ${resources.srcDirs[0]}"
println "output.classesDir = ${output.classesDir}"
println "output.resourcesDir = ${output.resourcesDir}"
}
}
}

compileJava.dependsOn downloadRedoc
copyWebui.dependsOn removeWebui
compileJava.dependsOn copyWebui</pre>

  • Create controller for APIs “WebRestController

package com.test.practise.controller;

import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RefreshScope
@RestController
@RequestMapping("/api")
public class WebRestController {

@RequestMapping("test")
public String test(){
return "test api data";
}


}
  • Create a view controller for enabling angular routes
<pre>package com.test.practise.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import springfox.documentation.annotations.ApiIgnore;


@Slf4j
@ApiIgnore
@Controller
public class ViewController {

    @RequestMapping({ "/","/welcome" })
    public String views() {
        return "forward:/index.html";
    }

}</pre>

This view controller will enable the spring to resolve these URL as angular URL.

 

Now we are good to go.Run the spring boot application using gradle bootRun.it will start the application.Once you will try to react the application from the browser, it will navigate you to google login first.

On Successful login, you will see the angular page.So till now we are pretty much done with authentication part. Now comes the routing part.

Now try to navigate to welcome page and setting page using above router.In this case, the welcome route will be successful but setting URL will fail, as we have not mentioned it in ViewController.

But when we try the routes which are below one, every route will work fine, as it is using angular routes.

For reference, you can check the GIT REPO with sample working code.

 

Advertisements

How to fail with MicroServices

microservices

 

As we all know, microservices is the new god in the tech industry. Yes, we always have old gods and new gods. Surely microservices have been accepted by the many of the companies, without even understanding how the business will be aligned with it.

Let’s not discuss what is microservices, but we should surely discuss what not to do if you don’t want fire on your ass.Today will try to discuss few of the shortcoming which I have felt after I have[NOT]proudly redesigned the system from monolith to microservices.

  • Domain is Important, But not the same Domain For every one

We all know the domain is very important for every application.Let’s make our code closer to the real-world entity. But does the sharing of domain make sense?Often people debate about how come we can have a different domain for the same entity.For example, let’s have a Flight domain, Flight will be flight, no matter it is in search service or booking service. Flight can have different attributes in both the context.And you will never replicate these attributes.Never create a single jar of domains to share it among different services. If you have to just kill other your services.

  • How services are talking to each other

Often developers create many microservices, they all the talking to each other in exactly the same way, it has been doing if they were a monolith.Direct interaction with microservice can be dangerous, can create a bottleneck for a process. Try to design a system in such a way that one service should not be waiting because of the action from another service. Utilize the power of asynchronous request using the messaging queue or any other design.Blocking request can be a hassle. Don’t just create distributed monolith

  • Complete System Design is Important, Microservice alone cannot do anything

When you are designing the microservice, you are not designing it for fun. It will eventually be plugged in the system to complete the bigger task. So know your system design. All the constraints against which your service will be run should be known. Development of microservice can be done in the isolation, but the birth of any microservice should always be an outcome of whole system design.

  • Be Ready before you start, DevOps if your key

devops.png

You can ask yourself, why the concept of microservice in a boom these days. This is because now we have such a capability which can handle such a massive complexity. So DevOps is too important. If your DevOps is not ready to support the proper microservice architecture, never ever think to go towards microservices.You can never create a home if your basic structure is not setup first.

  • Don’t try to clean the mess of other

144158-145685

Your service is not designed to clean the work of any other service. If any service is not doing its task completely, it’s not your duty to do it, ask that service to do it. There was a very simple example which I want to share, I was consuming one of the services whose owner was sitting beside me. Few of the attributes were missing from the result of that service, so I asked the owner to provide me the missing data, but the conversation finally went in a disappointed way. The owner asks me to fill the data by myself as getting those data points were very difficult for that service. And eventually, my service ends up doing a task which was not in the context of its boundary.

  • Learn from others, but don’t ever replicate their mistakes

We often share code, when a business is trying to solve the same kind of problems they often end up using the same type of approach/code for the different problem statement. There may be a chance good chance you will solve a problem very quickly by just simple copy paste, but you never know the constraints under which that code was written. With the power of that code, your are also copying the weakness of it. Learn from others, but never accept its solution for granted.

  • Let the services to micro, not the knowledge pool 

 

shareLogo

In the last point, I have discussed how dangerous the code replication. But This point doesn’t say we should blindly learn from other services. What I want to point out here is share the knowledge of other services, either the technical findings or the business constraints. Because in the end every micro service a broken piece of a giant puzzle

  • Let the code be agile, not just the process

Often people make the process agile but forget that if your code is not agile you cannot achieve agility. Make your services loosely coupled.Each service should be independent, and there should be minimum effort even if we have to rewrite the entire service.

  • Monolith business with microservices is as bad as Monolith

“This is the way things are done here”. One of the very old statements from old timers or from the business guys. But this will never help a project. If your system is going toward microservice, itis very important your business should also reflect the same, or honor it.At the end business thinking will be reflected on your system.

  • Common decision for every service is a hazard

Since every service is designed for its own purpose, a single and common solution can be dangerous for the lifecycle of services. It is very similar to the problem of selling shoes in the two very different geographic area.

  • Frameworks as awesome, but maybe not awesome for every service

Frameworks are awesome, it will hide the complexity from the developers, and magically do a lot of the stuff. But in-house framework can be a risk to the ongoing project. If you add the in-house framework to each and every service of your, you are binding the bugs associated with the framework to every service. It even often delays the release cycles.

  • Event Sourcing, I will be another Netflix

Don’t just use any of the modern design just for the sake of using it. Understand the business requirement first. Analyse the scope of your problem in terms of the traffic and availability of the system. What I have seen people often used event sourcing even to solve the simple problem stating the reason “We will be next Netflix”.

  • Different shops, with the same warehouse

Lest assume we have 5 different shops, but all the shops using the resource from a common pool. We have 10 resources in the pool and 5 services.Ideally 2 resources for each service, but if one of the services goes greedy/faulty and consumed 8 resources.Certainly there is a resource crunch for other services. even though other services are related to service one, but it got affected because of it. Same conditions are very common whenever we are using the same Database for the different microservices.Even in normal conditions, we know that database will be the choking point in the high traffic situation. Should implement the seperate database for separate services.

  • Pool of PolyGlot can be a pool of death

This point is more in the concern of the company.But not just company is affected, even the developers are affected, as it often increases the effort in maintenance. Choosing entirely different tech stack for each service can increase the project cost, as you need the tech specialist for each tech. Sharing of tech knowledge will be limited. And often the company cannot afford many tech specialists for tech, so eventually, it can let to the dependencies on few of the forks.

  • Anonymous service is a ghost

One of the common design we can see these days is, if few of the task which is not a good fit any of the existing services, developer eventually put all these tasks in the anonymous service, where no one knows what is happing. Service with no boundary, no exact reason. I call these kinds of services as a ghost. Ghost services are dangerous, and they are often the result of poor design or to support existing business for the time being. But remember you can never get rid of the ghost, and they will haunt you from time to time.

 

All these are the points which are the concern for me, maybe true or not true for you. These can be avoided or can be tackled with different designs, but do consider them before it late for your service.

 

 

 

AOP in Java Using Annotation

What is AOP? 

AOP stands for the Aspect-Oriented Programming. It is an approach to programming that allows global properties of a program to determine how it is compiled into an executable program. AOP can be used with object-oriented programming ( OOP ).It addresses the problem of cross-cutting concern.

All above is the technical definition, but now we will try to understand it in the more simpler term. Let suppose, as a developer you want to log request and response in the database whenever third-party API is called. One simple method is to add the logging code in the method itself. But should we add the code to log in method, as my method is not created for logging? Even if you are OK with adding the code to the method, now think if you have more than one method where you have to perform this logging. Now what?  Will we write the logging code in each and every method?

No, what we will do, we will find some magic way, by which our logs should be automatically written to the database. And that magic is AOP.

To read more about the AOP, read here.

How to use Annotation with AOP?

Since by now we should know that AOP needs pointcut to perform the magic.Now suppose you just want to log whenever any method is called. If you put a simple annotation on any method, and your work is done.

Here is an example of the same of how to use annotation for logging.

 

 

 

Java Annotations

AOP in Java Using Annotation

Java is one of my favorite languages. It is simple. But some of its features are still not used very commonly. One of them is Annotations. Annotation is very simple and one of the powerful concept of java. If you have worked the on framework like spring , you may have seen there are Annotation to do most of the setting.

Though we have used annotation in many ways , still I have not seen my developer going for the creation of their custom annotation. This blog helps us to understand when and where we can utilize the power of annotation.

What is Annotation?

import javax.annotation.PostConstruct;
import javax.validation.constraints.Max;

@Deprecated
public class Foo {

@Max(10)
int foo = 0;

@PostConstruct
private void setFoo() {
foo = 4;
}
@Deprecated
int returnFooCount() {
return foo;
}
}

Annotation is a tag which can have metadata that can be attached to class, interface, methods or fields to indicate some additional information which can be used by Java compiler and JVM.

Example:- @Deprecated,@Override,@PostConstruct are some of the in build java annotation which we have been using.Here you have seen we have added the annotation at class , at attribute and even at method.

Why Annotations?

Prior to Annotations, XML was often used to have the metadata. The Large set of Architectures and developers often believe that XML maintenance is difficult and it is not very easy to read. Something was needed which should be more close to code.Annotations are easy to understand and more readable.

Uses Of Annotations

  • Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings or to give some information to the compiler.[eg- @Serialization]
  • Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.[eg -lombok project – @Data,@Builder]
  • Runtime processing — Some annotations are available to be examined at runtime.[ It can be used as point cut in Aspect Oriented Programming]
  • Comments — Often people use annotation to provide comments, why I prefer annotations over the comment as it provides the structural way of commenting.[@Deprecated, any other custom annotation]

How Annotation Works?

Before using any concept we should understand how it works internally, only then we can explore the better way of using it and can use it properly.As we all know annotation does not contain any business knowledge.Then how it actually works?

When Java source code is compiled, annotations can be processed by compiler plug-ins called annotation processors. Processors can produce informational messages or create additional Java source files or resources, which in turn may be compiled and processed, and also modify the annotated code itself. The Java compiler conditionally stores annotation metadata in the class files, if the annotation has a RetentionPolicy of CLASS or RUNTIME(We will cover more about retention policy in further section). Later, the JVM or other programs can look for the metadata to determine how to interact with the program elements or change their behavior.

In addition to processing an annotation using an annotation processor, a Java programmer can write their own code that uses reflections to process the annotation

This package contains the interface called AnnotatedElement that is implemented by the Java reflection classes including Class, Constructor, Field, Method, and Package. The implementations of this interface are used to represent an annotated element of the program currently running in the Java Virtual Machine. This interface allows annotations to be read reflectively.

The AnnotatedElement interface provides access to annotations having RUNTIME retention. This access is provided by the getAnnotation, getAnnotations, and isAnnotationPresentmethods. Because annotation types are compiled and stored in byte code files just like classes, the annotations returned by these methods can be queried just like any regular Java object.

How to Build Custom Annotation?

Below is the simplest Annotation one can create.


public @interface CustomAnnotation {
}

 

Annotations itself can have some annotations, which tell us something about our new annotation.

  • Retention – It tells java how long any annotation will be retained during the different phase of code. Retention annotation have property RetentionPolicy which have 3 possible values:-
    • Source: Annotations are to be discarded by the compiler.
    • Class: Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time.[DEFAULT]
    • Runtime: Annotations are to be recorded in the class file by the compiler and retained by the VM at run time so they may be read reflectively.

@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
}

Note-A Retention meta-annotation has effect only if the meta-annotated type is used directly for annotation. It has no effect if the meta-annotated type is used as a member type in another annotation type.

  • Target: As we know we can put annotation at many different levels, at class, at attribute and many other. But as a developer, you might want to bound the use of your annotation at some level only, as your annotation can make sense some particular level.To declare the level this annotation is used.It has an attribute array of element type which can have all the possible level. There are different type elements in java.Most of them are self-explanatory.
    • Element Type
      • TYPE
      • FIELD
      • METHOD
      • PARAMETER
      • CONSTRUCTOR
      • LOCAL_VARIABLE
      • ANNOTATION_TYPE
      • PACKAGE
      • TYPE_PARAMETER [new in java 1.8]
        • eg  <T extends @A Object & @B Comparable, U extends @C Cloneable>
      • TYPE_USE [new in java 1.8] eg –
        • Map<@NonNull String, @NonEmpty List<@Readonly Document>> files;
  • Inherited:- If this annotation is present it will be inherited to the subclass, By default it is not present. It will only be effective when the annotation is given at class level.
  • Documented:-  Marks the annotation for inclusion in the documentation. Indicates that annotations with a type are to be documented by javadoc and similar tools by default.
  • Repeatable: Prior to Java 8 user were not allowed to give same anntation multiple times at same place.But If any annotation have repeatable annotation that can be put multiple time at same place.

Example

 

@Retention( RetentionPolicy.RUNTIME )
public @interface Cars {
       Manufacturer[] value() default{};
 }

@Repeatable(value = Cars.class )
public @interface Manufacturer {
String value();
};

@Manufacturer( "Mercedes Benz")
@Manufacturer( "Toyota")
@Manufacturer( "BMW")
@Manufacturer( "Range Rover")
public interface Car { 

}

Now we can give Manufacturer annotation multiple times to interface Car. Manufacturer annotation contains the Repeatable annotation which contains some other annotation as its value.

 

 

Now we know all the attribute of annotation, we can create annotations.


@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(value = {ElementType.TYPE})
public @interface CustomAnnotation {
String name();
String identifier() default "";
}

 

In our custom annotation, we have two properties name and identifier. A value doesn’t have any default property, so whenever we use this  CustomAnnotation it is mandated to give value attribute some value, otherwise, it gives error.On the other hand, identifier contain some default value, so we don’t have to compulsory give its value.

 

So, till now we have some basic idea how annotation work, and how to create an annotation.In the further blog, we will see the different situations where we can create our own custom annotations, and how to tell JVM to process these annotations.

Some Useful In-Build Annotations in Java

 

  • @GuardedBy
  • @Immutable
  • @NotThreadSafe
  • @ThreadSafe
  • @SuppressWarnings

Some Uses on Annotations

 


Useful Links

Difference between Dependency Management and Dependencies in Maven

Maven is a software management tool, use to manage information, dependencies and other things for a project.

It has two mechanisms to add the dependencies of other modules/project. One is Dependencies tag and other is Dependency Managment. People often wonder whats a difference between the two. An important question is when to use what?

First, of all, we should have an idea of what is multi module applications.As in the case in case of multi module applications only they differ.

A multi-module project is, as its name suggests, a project that consists of multiple modules, where a module is a project. You can think of a multi-module project as a logical grouping of sub-projects. The packaging of a multi-module project is “pom” since it consists of a pom.xml file but no artifact (jar, war, ear, etc).

multimodule-web-spring_projects

That’s a technical story. But it is not great if we are trying to teach some one. As concepts should be as simple as a story for a 12-year-old child. So let’s understand dependencies and dependency management.

There is a man called Peter, he has two ice cream parlors, Gelatos, and Baskin Robbins. Peter has two children Ron and Seria.

Peter has 2 ice cream in gelatos ice cream parlor – mango[ basic version ] and straberry[ moderate version] and 1 ice cream in Baskin Robbins – black current[high version].

Both Ron and Seria can have all the ice creams which their father has in Gelatos parlor, but they can have ice from Baskin Robbins only if they ask for it.Which means they can only have black current if they ask for specific it, but they don’t have to mention which version of black current they need, as their father Peter already know which kind of black current ice we have.

Here Peter is parent module and,  Ron and Seria are child modules.Gelatos is dependencies tag and Baskin Robin is Dependency Management tag.

screen-shot-2015-06-28-at-18-18-31-480x275

So all the dependencies present in dependencies tag will be available to all its child modules.But all the dependencies present in dependency management of parent module will be available to the child only if those dependencies are declared in dependencies tag of child module.

So why are we even using dependency management if dependencies tag passes all the dependency to its children?

  1. As all the children might not need all the dependencies present in parent module, so it is always wise to use Dependency Managment.
  2. Using Dependency Managment we can create a consistency of which version and tag of any artifact which we are using through out the application.[It help to maintain the version of artifact]
  3. Dependency Managment manage version, scope, and exclusion of artifact in child modules.

Example –

Parent POM- A

</pre>
<pre><?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.test</groupId>
    <artifactId>A</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>B</module>
        <module>C</module>
    </modules>

    <dependencies>
            <dependency>
            <groupId>com.external</groupId>
            <artifactId>d1</artifactId>
            <version>1</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.external</groupId>
                <artifactId>d2</artifactId>
                <version>1</version>
            </dependency>
            <dependency>
                <groupId>com.external</groupId>
                <artifactId>d3</artifactId>
                <version>1</version>
            </dependency>
        </dependencies>

    </dependencyManagement>
</project></pre>
<pre>

It has 2 child module A and B. Parent A has 3 dependencies in total:-

  • d1 [Inside dependencies tag]
  • d2 [Inside dependency management tag]
  • d3 [Inside dependency management tag]

 

 Child Pom B

</pre>
<pre><?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.test</groupId>
        <artifactId>A</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.test</groupId>
    <artifactId>B</artifactId>
    <packaging>pom</packaging>

    <dependencies>
        <dependency>
            <groupId>com.external</groupId>
            <artifactId>d2</artifactId>
        </dependency>
        <dependency>
            <groupId>com.external</groupId>
            <artifactId>d4</artifactId>
            <version>1</version>
        </dependency>
    </dependencies>
</project></pre>
<pre>

It will have access to 3 artifacts

  • d1 [coming from dependencies of parent ]
  • d2 [coming from  parent dependency management as mention in its dependencies tag]
  • d4 [coming from its dependencies tag]

Note:- It will not have the d3 artifact, as d3 is mention dependency management tag of parent pom [POM A] but not present in child pom [POM B].

Child Pom C

</pre>
<pre><?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.test</groupId>
        <artifactId>A</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.test</groupId>
    <artifactId>C</artifactId>
    <packaging>pom</packaging>

    <dependencies>
        <dependency>
            <groupId>com.external</groupId>
            <artifactId>d3</artifactId>
        </dependency>
        <dependency>
            <groupId>com.external</groupId>
            <artifactId>d5</artifactId>
            <version>1</version>
        </dependency>
    </dependencies>
</project></pre>
<pre>

Similarly, It will have access to 3 artifacts

  • d1 [coming from dependencies of parent ]
  • d3 [coming from  parent dependency management as mention in its dependencies tag]
  • d5 [coming from its dependencies tag]

Note:- It will not have the d3 artifact, as d3 is mention dependency management tag of parent pom [POM A] but not present in child pom [POM B].


 

Further Reading – http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

 

What Yagni Is?

Often developer debates a lot about what YAGNI is actually. Writing any new piece of code bind developer’s hand in the name of YAGNI.

I have worked in both product base company and service based company.I personally feel that YAGNI is more appreciated in the service based company, as in product based any extra feature is helpful.

People back YAGNI by saying “You don’t wipe before you shit.”.So true.We should not increase the scope of the problem as it may open the gates of new bugs.So YAGNI tells us “don’t write any extra/new code unless it is actually required”.

I agree with the last quoted statement.But should we bind our hands in implementing the requirement in a fashion that it should always be open for extensibility, or to write any functionality in a more generic way so that it can be reused any time in near future?

So, what my definition of YAGNI is: – Always write the code in the scope of the current requirement, but don’t cry out YAGNI if you want to solve it in the generic or extensible way.The code should close for modification but open for extensibility.

Try to solve problems in generic ways, that can be used in future.

Difference Between Generative and Discriminative machine learning

To understand these two models we first have to see what is the difference between joint probability [P(x,y)] and conditional probability[P(x|y)].

Joint probability:  p(A and B).  The probability of event A and event B occurring.  It is the probability of the intersection of two or more events.  The probability of the intersection of A and B may be written p(A ∩ B). Example:  the probability that a card is a four and red =p(four and red) = 2/52=1/26.  (There are two red fours in a deck of 52, the 4 of hearts and the 4 of diamonds).

Conditional probability:  p(A|B) is the probability of event An occurring, given that event B occurs. Example:  given that you drew a red card, what’s the probability that it’s a four (p(four|red))=2/26=1/13.  So out of the 26 red cards (given a red card), there are two fours so 2/26=1/13.

For better understanding, click here for more on probability.

generative algorithm models how the data was generated in order to categorize a signal. It asks the question: based on my generation assumptions, which category is most likely to generate this signal? Let’s say you have input data x and you want to classify the data into labels y. A generative model learns the joint probability distribution p(x,y). A generative algorithm models how the data was “generated”, so you ask it “what’s the likelihood this or that class generated this instance?” and pick the one with the better probability.

discriminative algorithm does not care about how the data was generated, it simply categorizes a given signal. Discriminative model learns the conditional probability distribution p(y|x) – which you should read as the probability of y given x. A discriminative algorithm uses the data to create a decision boundary, so you ask it “what side of the decision boundary is this instance on?

The fundamental difference between discriminative models and generative models is:

  • Discriminative models learn the (hard or soft) boundary between classes
  • Generative models model the distribution of individual classes

Given input data point x, the aim is to predict continuous (regression) or discrete (classification) output. That is given x, we are interested in modeling p(y|x). There are three approaches to this:

1. Generative Models:
One way is to model p(x, y) directly. Once we do that, we can obtain p(y|x) by simply conditioning on x. And we can then use decision theory to determine class membership i.e. we can use loss matrix, etc. to determine which class the point belongs to (such an assignment would minimize the expected loss). For e.g. in Naive Bayes model, you can learn p(y), the prior class probabilities from the data. You can also learn p(x|y) from the data using said maximum likelihood estimation (or you can Bayes estimator if you will). Once you have p(y) and p(x|y), p(x, y) is not difficult to find out.

2. Discriminative Models:
Instead of modeling p(x, y), we can directly model p(y|x), for e.g. in logistic regression p(y|x) is assumed to be of the form 1 / (1 + exp(-sigma(wi. xi))). All we have to do in such a case is to learn weights that would minimize the squared loss.

Generative models often outperform discriminative models on smaller datasets because their generative assumptions place some structure on your model that prevent overfitting. For example, let’s consider Naive Bayes vs. Logistic Regression. The Naive Bayes assumption is of course rarely satisfied, so logistic regression will tend to outperform Naive Bayes as your dataset grows (since it can capture dependencies that Naive Bayes can’t). But when you only have a small data set, logistic regression might pick up on spurious patterns that don’t really exist, so the Naive Bayes acts as a kind of regularizer on your model that prevents overfitting. There’s a paper by Andrew Ng and Michael Jordan on discriminative vs. generative classifiers that talks about this more.

Whenever an algorithm involves assuming, calculating or estimating the distribution of Y, it is generative, or simply put, if the algorithm cares about the distribution of Y, it is generative, if not, then it is discriminative.

Now a Small story to tell your 12-year-old kid, so that they can also understand the difference between these two models

Let’s say you have two kids “Gen” and “Dis”, and since their birth, they never opened their eyes. Today is the first day they will open their eyes, and you want to celebrate this occasion by teaching them the difference between Cat and Dog. You take them to pet store nearby.

Before showing around, you tell Gen and Dis to pay special attention to color, size, eye color, fur size, their voice etc.(feature set) of the pets they are going to see. After the end of this visit, you want to check if they understood the difference between cat and dog.

Now you give two photos one of a cat and one of a dog to Dis and ask which one is which. Dis has meticulously written down several conditions like if the voice sounds like meow and eyes are blue or green and has stripes with color brown or black then the animal is a cat. Thanks to her relatively simple rules, she quickly detected which one is a cat and which one is a dog.

Now instead of giving two photos you gave Gen two pieces of blank paper and ask her to draw what a cat and a dog looks like.

Well now, given any photo Gen can also tell which one is cat and which one is dog based on the drawing she created. In most cases drawing of cat and dog was unnecessary and time consuming for the task of detection which one is a cat.

But if there were only a few dogs and cats to look for Gen and Dis (low training data). In such cases if you give a photo of a brown dog with stripes with blue eyes, there is a chance that Dis would mark it as a cat. While Gen has her drawing and she can better detect that this photo is of a dog.

If you ask Gen to pay attention to more things(features), it will create a better sketch. But, if you show more examples(data-set) of cat and dog, Dis would mostly be better than Gen.

Since Dis is very meticulous in her observations if you ask her to pay attention to more features it will create more complicated rules(overfitting) and the chance of wrongly identifying a cat and a dog will increase, but that would not happen easily with Gen.

What if before going to pet store I don’t tell them that there are only two types of animal(no labeled data). Dis would fail completely because she will not know what to look for while Gen would be able to draw the sketch anyway. This is a huge advantage sometimes(semi-supervised).

Now let me reveal the suspense which you might already know: Dis is for discriminative and Gen is for generative.

Continue reading