Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Saturday, August 11, 2018

Create Simple Microservice project to understand the concepts

I have searched throughout the web and below is the sample code i have found.
https://spring.io/blog/2015/07/14/microservices-with-spring

below are the simplified steps in creating running the project



created pom with all dependencies and build the maven project


1.  create package "io.pivotal.microservices.services.registration"
a.)RegistrationServer.java
b.) registration-server.yml inside "src\main\resources"
c.) run RegistrationServer.java and access http://localhost:1111/
run RegistrationServer with jar created. 

2. Create account services
a.) create package "io.pivotal.microservices.services.accounts" and service class "AccountsServer.java"
This class need "AccountsServer.class" and "AccountRepository.java"
b.) Business logic for Account. create package "io.pivotal.microservices.accounts"
create "Account.java"  pojo
create "AccountRepository.java"
create "AccountsConfiguration.java"
create "AccountsController.java". --> need exceptioon class also for this.
create "HomeController.java"
c.) create exception class for account
create package "io.pivotal.microservices.exceptions" and class "AccountNotFoundException.java"

Now error in the "AccountsServer.java"  will be resolved.

Run "AccountsServer.java" -->

3. Errors
a.)error [db-config.properties] cannot be opened because it does not exist

Added "db-config.properties" to folder "src\main\resources"

b.)Error
class path resource [testdb/schema.sql] cannot be opened because it does not exist
create folder "testdb" inside "resources" and Added "schema.sql" and "data.sql"

4. Now run "http://localhost:1111/" , you can see the account service registered.
for more info gotot "http://localhost:1111/eureka/apps/"

Alternativel go and see "http://localhost:1111/eureka/apps/ACCOUNTS-SERVICE"

5. Configuration options
Registration takes upto 30s cause this is default client refresh time. Can change setting "eureka.instance.leaseRenewalIntervalInSeconds"
Note : Smaller numbers are not recommened in Prod

eureka:
  instance:
    leaseRenewalIntervalInSeconds: 5         # DO NOT DO THIS IN PRODUCTION



6. Acessing microservice web service

a.) create package "io.pivotal.microservices.services.web"
b.) create classes
"Account.java"
HomeController.java
SearchCriteria.java
WebAccountsController.java  --> needs "WebAccountsController"
WebAccountsService.java
WebServer.java

7. Make sure you have yml files for each service
registration-server.yml
accounts-server.yml
web-server.yml

8. Running Three services without building jar
mvn spring-boot:run -Dstart-class=io.pivotal.microservices.services.registration.RegistrationServer
mvn spring-boot:run -Dstart-class=io.pivotal.microservices.services.accounts.AccountsServer
mvn spring-boot:run -Dstart-class=io.pivotal.microservices.services.web.WebServer

9. Building jar file.
As we have 3 main classes we need to specify the main class inside POM file.
In this case we create onc single class with main method "Main.java"  and call other services via that class

inside POM

<properties>
<start-class>io.pivotal.microservices.services.Main</start-class>
</properties>

Then create Main class inside package "io.pivotal.microservices.services"

Call the each service and run as below

java -jar target/microservices-demo-2.0.0.RELEASE.jar registration
java -jar target/microservices-demo-2.0.0.RELEASE.jar accounts
java -jar target/microservices-demo-2.0.0.RELEASE.jar web










Create Micro service Project with many services and running one by one

You may have build the all the microservices in a single project or One project has many micro services.

In that case how to run those services picking up one by one as needed.

Example i have taken  from

https://spring.io/blog/2015/07/14/microservices-with-spring


eg : we have three micro services projects.
1. Registration server - eureka server
2. Account service
3. Web

How to run without building the jar:

we use maven and use spring-boot plugin to specify 'run' and give the main class with "-Dstart-class" tag

below is the three sample commands, run from the sample project directory where the POM file exist.(where you run mvn clean package  command)

mvn spring-boot:run -Dstart-class=io.pivotal.microservices.services.registration.RegistrationServer

mvn spring-boot:run -Dstart-class=io.pivotal.microservices.services.accounts.AccountsServer

mvn spring-boot:run -Dstart-class=io.pivotal.microservices.services.web.WebServer



How to run with Jar

Since we have few main classes

1. We need to specify the maven what is our main class

<properties>
<start-class>io.pivotal.microservices.services.Main</start-class>
</properties>

2. Create One single class with Main method. 
We call it Main.java
As we can. specify only one main class, we need to create a class with one main method which will guide to / call to other main methods (RegistrationServer.java , AccountsServer.java, WebServer.java)



3. Run jar with calling each service via Main.java
open three command lines and execute below three command, which will up three services

java -jar target/microservices-demo-2.0.0.RELEASE.jar registration
java -jar target/microservices-demo-2.0.0.RELEASE.jar accounts
java -jar target/microservices-demo-2.0.0.RELEASE.jar web


----------------------------------------------------------------below code snipet for Main.java--------------

If you do not create Main.java, still maven will build the project without error, but running this you will get 
Exception in thread "main" java.lang.ClassNotFoundException: io.pivotal.microservices.services.Main


----------------------------------------------------------------------------------




package io.pivotal.microservices.services;

import io.pivotal.microservices.services.accounts.AccountsServer;
import io.pivotal.microservices.services.registration.RegistrationServer;
import io.pivotal.microservices.services.web.WebServer;

/**
 * Allow the servers to be invoked from the command-line. The jar is built with
 * this as the Main-Class in the jar's MANIFEST.MF.
 * 
 * @author Paul Chapman
 */
public class Main {

 public static void main(String[] args) {

  String serverName = "NO-VALUE";

  switch (args.length) {
  case 2:
   // Optionally set the HTTP port to listen on, overrides
   // value in the -server.yml file
   System.setProperty("server.port", args[1]);
   // Fall through into ..

  case 1:
   serverName = args[0].toLowerCase();
   break;

  default:
   usage();
   return;
  }

  if (serverName.equals("registration") || serverName.equals("reg")) {
   RegistrationServer.main(args);
  } else if (serverName.equals("accounts")) {
   AccountsServer.main(args);
  } else if (serverName.equals("web")) {
   WebServer.main(args);
  } else {
   System.out.println("Unknown server type: " + serverName);
   usage();
  }
 }

 protected static void usage() {
  System.out.println("Usage: java -jar ...  [server-port]");
  System.out.println(
    "     where server-name is 'reg', 'registration', " + "'accounts' or 'web' and server-port > 1024");
 }
}

Friday, August 10, 2018

Error building micro services app

https://spring.io/blog/2015/07/14/microservices-with-spring

Below shows the error. Solution is adding below snipet , "start-class" for the POM. Try building with "mvn clean package"

Solution :

<properties>
<start-class>io.pivotal.microservices.services.Main</start-class>
</properties>


Then run the jar with specifying which main method needs to be choose.

eg :
java -jar microservices-demo-2.0.0.RELEASE.jar account
java -jar microservices-demo-2.0.0.RELEASE.jar account
java -jar microservices-demo-2.0.0.RELEASE.jar account


------ Error --------------------------------

[INFO] Finished at: 2018-08-10T16:41:48+05:30
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.1.RELEASE:repackage (default) on project EurekaServer1: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:2.0.1.RELEASE:repackage failed: Unable to find a single main class from the following candidates
[io.pivotal.microservices.services.registration.RegistrationServer, io.pivotal.microservices.services.web.WebServer] ->
[Help 1]org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.1.RELEASE:repackage (default) on project EurekaServer1: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:2.0.1.RELEASE:repackage failed: Unable to find a single main class from the following candidates
[io.pivotal.microservices.services.registration.RegistrationServer, io.pivotal.microservices.services.web.WebServer] at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:213) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81) at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128) at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305) at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192) at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105) at org.apache.maven.cli.MavenCli.execute (MavenCli.java:954) at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288) at org.apache.maven.cli.MavenCli.main (MavenCli.java:192) at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke (Method.java:497) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289) at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415) at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:2.0.1.RELEASE:repackage failed: Unable to find a single main class from the following candidates
[io.pivotal.microservices.services.registration.RegistrationServer, io.pivotal.microservices.services.web.WebServer] at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:148) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81) at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128) at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305) at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192) at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105) at org.apache.maven.cli.MavenCli.execute (MavenCli.java:954) at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288) at org.apache.maven.cli.MavenCli.main (MavenCli.java:192) at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke (Method.java:497) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289) at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415) at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)Caused by: java.lang.IllegalStateException: Unable to find a single main class from the following candidates
[io.pivotal.microservices.services.registration.RegistrationServer, io.pivotal.microservices.services.web.WebServer] at org.springframework.boot.loader.tools.MainClassFinder$SingleMainClassCallback.getMainClassName (MainClassFinder.java:451) at org.springframework.boot.loader.tools.MainClassFinder$SingleMainClassCallback.access$100 (MainClassFinder.java:421) at org.springframework.boot.loader.tools.MainClassFinder.findSingleMainClass (MainClassFinder.java:205) at org.springframework.boot.loader.tools.Repackager.findMainMethod (Repackager.java:333) at org.springframework.boot.loader.tools.Repackager.findMainMethodWithTimeoutWarning (Repackager.java:322) at org.springframework.boot.loader.tools.Repackager.buildManifest (Repackager.java:293) at org.springframework.boot.loader.tools.Repackager.repackage (Repackager.java:238) at org.springframework.boot.loader.tools.Repackager.repackage (Repackager.java:195) at org.springframework.boot.maven.RepackageMojo.repackage (RepackageMojo.java:221) at org.springframework.boot.maven.RepackageMojo.execute (RepackageMojo.java:208) at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81) at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128) at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305) at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192) at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105) at org.apache.maven.cli.MavenCli.execute (MavenCli.java:954) at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288) at org.apache.maven.cli.MavenCli.main (MavenCli.java:192) at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke (Method.java:497) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289) at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415) at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
[ERROR]
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR]
[Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionExceptionC:\BackUp_2016_07_14\NonFilter\Projects\EAG\code\Spring\SpringBoot\EurekaServer1>




Now we have another error running jar with argument specifying the service.

Reason: we have not added the Main.java  class we have specified inside the POM. when we build the jar, earlier we had an issue with too many main methods. As we need to get rid of that we specifies a class which needs to be taken as a main class inside POM.
It build the jar without checking the existence of the class.

Solution :
So we create the Main.java class in the specified package.

Error is below when class in not present.

------------------------
Exception in thread "main" java.lang.ClassNotFoundException: io.pivotal.microservices.services.Main
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:93)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:46)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)



Monday, July 30, 2018

Creating First SpringBoot Application

1. created maven project

mvn archetype:generate -DgroupId=com.test -DartifactId=SpringBootTest -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. To make this is a springboot application, we need to add the dependencies related to Springboot.

https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started-first-application.html

 add "spring-boot-starter-parent" in "parent"  section.

 This is special starter
   a.) Provides useful maven defaults
   b.) Provides a dependancy management section - this helps you to ommit the "version" tags for "blessed" dependancies

 
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>

3. Add other "Starters" which need to build a specific type of application.
  Let's say , we are going to build web, we add "spring-boot-starter-web" as dependency
 
Before adding the "spring-boot-starter-web" as dependency , we can check what we have with us currently with "mvn dependency:tree" command
This will give us an output as below.

[INFO] com.test:SpringBootTest:jar:1.0-SNAPSHOT
[INFO] \- junit:junit:jar:3.8.1:test
[INFO] ------------------------------------------------------------------------


"mvn dependency:tree" command prints the tree version of the dependancies in your project.

Important : "spring-boot-starter-parent" does not provides any dependancy itself. Not in the list.

So let's add neccessary dependancies and check the tree. As we are going to make web app, let's add the dependancy.

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

If you run "mvn dependency:tree" again ,  you will see the number of dependancies including springboot

[INFO] com.test:SpringBootTest:jar:1.0-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.0.3.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:2.0.3.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:2.0.3.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.0.3.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.0.3.RELEASE:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] |  |  |  |  +- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO] |  |  |  |  \- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] |  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.10.0:compile
[INFO] |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.10.0:compile
[INFO] |  |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
[INFO] |  |  +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO] |  |  +- org.springframework:spring-core:jar:5.0.7.RELEASE:compile
[INFO] |  |  |  \- org.springframework:spring-jcl:jar:5.0.7.RELEASE:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.19:runtime
[INFO] |  +- org.springframework.boot:spring-boot-starter-json:jar:2.0.3.RELEASE:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.6:compile
[INFO] |  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
[INFO] |  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.9.6:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.6:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.6:compile
[INFO] |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.6:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.0.3.RELEASE:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.31:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.31:compile
[INFO] |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.31:compile
[INFO] |  +- org.hibernate.validator:hibernate-validator:jar:6.0.10.Final:compile
[INFO] |  |  +- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile
[INFO] |  |  \- com.fasterxml:classmate:jar:1.3.4:compile
[INFO] |  +- org.springframework:spring-web:jar:5.0.7.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-beans:jar:5.0.7.RELEASE:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:5.0.7.RELEASE:compile
[INFO] |     +- org.springframework:spring-aop:jar:5.0.7.RELEASE:compile
[INFO] |     +- org.springframework:spring-context:jar:5.0.7.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:5.0.7.RELEASE:compile
[INFO] \- junit:junit:jar:3.8.1:test
[INFO] ------------------------------------------------------------------------



4. writting code.

Let's create a class with name "Example" and put inside "src/main/java".
Imporatnt: By default, maven compiles sources from "src/main/java".

So the file name will be "src/main/java/Example.java"

-------------------------------------------------------------------------------

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*;

@RestController
@EnableAutoConfiguration
public class Example {

@RequestMapping("/")
String home() {
return "Hello World!";
}

public static void main(String[] args) throws Exception {
SpringApplication.run(Example.class, args);
}

}

------------------------------------------------------------------------------

5. Run application.
 Simply run the main class. This will deploy your main class in tomcat server and you can view the output by simply calling "http://localhost:8080/" from your web browser.

 This will give the output

 ---------------
 Hello World

 ---------------

 6. Creating an executable jar

 We can create an executable jar using "spring-boot-maven-plugin" in "pom.xml". Add the below, just below the "dependencies"

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


but if you have more than one class with main method, then better to sepcify the class you need to run

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>

<configuration>
<mainClass>Example.class</mainClass>
<layout>ZIP</layout>
</configuration>
</plugin>
</plugins>
</build>



Important :
"spring-boot-starter-parent" POM includes configuration to bind the "repackage" goal. In simple, If you do not use the parent POM, you have to declare this configuration of your own.



Below is the final POM file.

--------------------------------------------------------------------

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>SpringBootTest</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringBootTest</name>
<url>http://maven.apache.org</url>

<!-- spring boot parent starter -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>

<dependencies>

<!-- Spring boot web app -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>

<configuration>
<mainClass>Example.class</mainClass>
<layout>ZIP</layout>
</configuration>
</plugin>
</plugins>
</build>
</project>





  Understanding annotations

 @RestController -> know as a stereotype annotation, provides a hint for the people reading the code and for the Spring , that class plays a specific role.
 So in this case, our class is a web @Controller.

 @RequestMapping --> provides  “routing” information.
 tells Spring that any HTTP request with the "/" path should be mapped to the "home " method.

 @RestController --> Spring to render the resulting string directly back to the caller.

 @RestController and @RequestMapping annotations are Spring MVC annotations. (They are not specific to Spring Boot.)

 @EnableAutoConfiguration -->
 tells Spring Boot to “guess” how you want to configure Spring, based on the jar dependencies that you have added. As we have added "spring-boot-starter-web" Tomcat and Spring MVC, the auto-configuration assumes that you are developing a web application and sets up Spring accordingly.


Our main method delegates to Spring Boot’s SpringApplication class by calling run. SpringApplication bootstraps our application, starting Spring, which, in turn, starts the auto-configured Tomcat web server. We need to pass Example.class as an argument to the run method to tell SpringApplication which is the primary Spring component. The args array is also passed through to expose any command-line arguments.

SpringBoot Application error

Below is the Exception comes when you execute : mvn package

Issue: You have more than one class inside the application with 'main" method

solution : Find the other main method and delete or comment that. Or specify the class you need to refer the main method.
Hint : If you create a project using a maven template, most probably it will create a App.java class with main method. So look for that.

You can easily solve by stating the main class. eg: main class is Example.java


<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>

<configuration>
<mainClass>Example.class</mainClass>
<layout>ZIP</layout>
</configuration>
</plugin>
</plugins>
</build>

for more information refer

https://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html
----------------------------------------------------------------------------------------------------------------

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.3.RELEASE:repackage (default) on project SpringBootTest: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:2.0.3.RELEASE:repackage failed: Unable to find main class -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.3.RELEASE:repackage (default) on project SpringBootTest: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:2.0.3.RELEASE:repackage failed: Unable to find main class
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:225)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:2.0.3.RELEASE:repackage failed: Unable to find main class
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:110)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
        ... 19 more
Caused by: java.lang.IllegalStateException: Unable to find main class
        at org.springframework.boot.loader.tools.Repackager.buildManifest(Repackager.java:300)
        at org.springframework.boot.loader.tools.Repackager.repackage(Repackager.java:238)
        at org.springframework.boot.loader.tools.Repackager.repackage(Repackager.java:195)
        at org.springframework.boot.maven.RepackageMojo.repackage(RepackageMojo.java:220)
        at org.springframework.boot.maven.RepackageMojo.execute(RepackageMojo.java:207)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
        ... 20 more
[ERROR]
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException

Sunday, August 6, 2017

Spring Boot - Article 1

So what is Spring Boot ?

You must have heard the word "Spring". It is well known framework for Java developers. In simple, Spring is basically an Application Framework (which includes so many concepts like inversion of container...etc) for Java developers which helps to build applications using Spring's core features and more powerful features with build in and plugin extensions.

So what is Spring Boot then ?
Here are few explanation i came a cross in internet.

Spring Boot is a brand new framework from the team at Pivotal, designed to simplify the bootstrapping and development of a new Spring application. The framework takes an opinionated approach to configuration, freeing developers from the need to define boilerplate configuration.

Well looks to be lots of jargon of words :)

So what is it ?

Spring Boot makes it easy to create stand-alone, production-grade, Spring based applications that you can just run.

Here are some of the words/jargon which comes with the Spring Boot


  • Opinionated
  • Convention over Configuration
  • Stands alone
  • Production ready






Thursday, April 16, 2015

Spring Expression Language

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html

You can find very descriptive details from the above mention link in the spring docs. The definition include as below..

The Spring Expression Language (SpEL for short) is a powerful expression language that supports querying and manipulating an object graph at runtime. The language syntax is similar to Unified EL but offers additional features, most notably method invocation and basic string templating functionality.


I am not going to rewrite what has already being well described with the spring docs, instead i thought of sharing some exceptions which might you experience.

This is about the initial example of "Hello world " as Spring expression.

You can simply create a class and inside main method you can directly run the code. I have just included inside static method.

So below is the code


ExpressionEvaluationWithSEI.java
------------------------------------------------------------------------------------------------------
package com.spel;



import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

/**
 * http://docs.spring.io/spring/docs/current/spring-framework-reference/html/
 * expressions.html
 *
 * Expression Evaluation using Spring’s Expression Interface
 *
 * @author APrasad
 *
 */
public class ExpressionEvaluationWithSEI {

public static void evaluateLiteralStringExpression() {
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("'Hello World'");
String message = (String)expression.getValue();
System.out.println("message ="+message);

}

public static void main(String[] args) {
ExpressionEvaluationWithSEI.evaluateLiteralStringExpression();
}
}


------------------------------------------------------------------------------------------------------
This will have simple output

output
=============================================================
message =Hello World
=============================================================


Note : The word "Hello World"  is within the single quotes..... So if any case if you miss the single quotes , then you will probably witness below exception.

change new code

------------------------------------------------------------------------------------------------------
Expression expression = parser.parseExpression("Hello World");
//Note :: I have remove the single quotes around the literal expression Hello World
------------------------------------------------------------------------------------------------------

output
=============================================================
Exception in thread "main" org.springframework.expression.spel.SpelParseException: EL1041E:(pos 6): After parsing a valid expression, there is still more data in the expression: 'World'
at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:118)
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:56)
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:1)
at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:66)
at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:56)
at com.spel.ExpressionEvaluationWithSEI.evaluateLiteralStringExpression(ExpressionEvaluationWithSEI.java:22)
at com.spel.ExpressionEvaluationWithSEI.main(ExpressionEvaluationWithSEI.java:29)

=============================================================



Now let's also check other functionality given with the expression.


ExpressionEvaluationWithSEI.java
------------------------------------------------------------------------------------------------------
package com.spel;



import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

/**
 * http://docs.spring.io/spring/docs/current/spring-framework-reference/html/
 * expressions.html
 *
 * Expression Evaluation using Spring’s Expression Interface
 *
 * @author APrasad
 *
 */
public class ExpressionEvaluationWithSEI {

public static void evaluateLiteralStringExpression() {
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("'Hello World'");
String message = (String)expression.getValue();
System.out.println("message ="+message);

//newly added
System.out.println("getExpressionString ="+expression.getExpressionString());
System.out.println("toString ="+expression.toString());
System.out.println("getValueType ="+expression.getValueType());
}

public static void main(String[] args) {
ExpressionEvaluationWithSEI.evaluateLiteralStringExpression();
}
}

------------------------------------------------------------------------------------------------------

output
=============================================================
message =Hello World
getExpressionString ='Hello World'
toString =org.springframework.expression.spel.standard.SpelExpression@18019707
getValueType =class java.lang.String

=============================================================



Thursday, March 26, 2015

Exceptions in spring configuration

This is to give you some details about the exceptions and how will they come. I have refered the code I explained in the
http://cgenit.blogspot.com/2015/03/spring-basic-collection-list.html  to generate the exceptions.

Here we have used a list points inside the Triangle class and we are injecting the beans for the Triangle.
We have circle bean definition , another bean we use.

So to refresh the xml configuration, it will look like below


spring.xml
--------------------------------------------------------------------------------------------------------------------
<bean name="triangle" class="org.aop.model.Triangle">
<property name="name" value="Traingle name"></property>
<property name="points">
<list>
<ref bean="zeroPoint" />
<ref bean="pointTwo" />
<ref bean="pointThree" />
</list>
</property>
</bean>

<bean name="zeroPoint" class="org.aop.model.Point">
<property name="x" value="0"></property>
<property name="y" value="0"></property>
</bean>
<bean name="pointTwo" class="org.aop.model.Point">
<property name="x" value="20"></property>
<property name="y" value="0"></property>
</bean>
<bean name="pointThree" class="org.aop.model.Point">
<property name="x" value="0"></property>
<property name="y" value="20"></property>
</bean>

<bean name="circle" class="org.aop.model.Circle">
<property name="name" value="Circle name"></property>
</bean>
---------------------------------------------------------------------------------------------------------------

 Error No 1: Let's add a circle to the points list. We have defined list as Points generic list inside the Triangle object.

-------------------------------------------------------------------------------------------

package org.aop.model;

import java.util.List;

public class Triangle {
private String name;
private List points;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getPoints() {
return points;
}
public void setPoints(List points) {
this.points = points;
}
@Override
public String toString() {
return "Triangle [name=" + name + ", points=" + points + "]";
}

}

------------------------------------------------------------------------------

Now this will give us conversion error and tell us bean creation does not know any strategy to convert the circle bean to Point. I have highlighted the text line where we can identify the error.


error code , adding circle bean highlighted.

----------------------------------------------------

<bean name="triangle" class="org.aop.model.Triangle">
<property name="name" value="Traingle name"></property>
<property name="points">
<list>
<ref bean="zeroPoint" />
<ref bean="pointTwo" />
<ref bean="pointThree" />
<ref bean="circle" />
</list>
</property>
</bean>

--------------------------------------------


Below is the exception.
---------------------------------------------------------------------------------------------------

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'triangle' defined in class path resource [spring.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.util.ArrayList' to required type 'java.util.List' for property 'points'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.aop.model.Circle$$EnhancerBySpringCGLIB$$bb74d74b] to required type [org.aop.model.Point] for property 'points[3]': no matching editors or conversion strategy found
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at org.aop.main.AppMain.main(AppMain.java:10)
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.util.ArrayList' to required type 'java.util.List' for property 'points'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.aop.model.Circle$$EnhancerBySpringCGLIB$$bb74d74b] to required type [org.aop.model.Point] for property 'points[3]': no matching editors or conversion strategy found
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:463)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:494)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:488)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1463)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
... 11 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [org.aop.model.Circle$$EnhancerBySpringCGLIB$$bb74d74b] to required type [org.aop.model.Point] for property 'points[3]': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)
at org.springframework.beans.TypeConverterDelegate.convertToTypedCollection(TypeConverterDelegate.java:562)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:202)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:448)
... 17 more


------------------------------------------------------------------------------------------------------------------------


2. Error 2: let's try to add the Triangle class to Point bean definition.
Point class has two properties with name "x" and "y" and we have defined the values to be inject in bean creation in our spring.xml configuration. 
Now we have mistakenly given Triangle class to place where we need to give Point class.
As Triangle does not have setter for the defined property values it will give error when setting those properties when creating bean from the definition given.

error code inside spring.xml


------------------------------------------------------------------------------------------------------------------------
<bean name="zeroPoint" class="org.aop.model.Triangle">
<property name="x" value="0"></property>
<property name="y" value="0"></property>
</bean>
------------------------------------------------------------------------------------------------------------------------

Below is the exception
------------------------------------------------------------------------------------------------------------------------
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'triangle' defined in class path resource [spring.xml]: Cannot resolve reference to bean 'zeroPoint' while setting bean property 'points' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'zeroPoint' defined in class path resource [spring.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'x' of bean class [org.aop.model.Triangle]: Bean property 'x' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:326)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:350)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:154)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1417)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at org.aop.main.AppMain.main(AppMain.java:10)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'zeroPoint' defined in class path resource [spring.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'x' of bean class [org.aop.model.Triangle]: Bean property 'x' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1453)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:320)
... 17 more
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'x' of bean class [org.aop.model.Triangle]: Bean property 'x' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1043)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:903)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:57)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1450)
... 25 more

------------------------------------------------------------------------------------------------------------------------

Spring Basic - Collection List

Let's look at how we do the bean definitions to the List, Collection object.
Here also we use basic spring maven project and introduce the Point object which we use as a attribute in the Triangle to set the three points.
We are giving the tree points as a list to Triangle.
basic ode structure and package is as below
http://cgenit.blogspot.com/2015/03/aop-basic-application-code-and.html

The new class Point , we need to define three instances , as Triangle requires three points.
Point class will be as follows

Point .java
-------------------------------------------------------------------------------------------
package org.aop.model;

public class Point {
private int x;
private int y;

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

public int getY() {
return y;
}

public void setY(int y) {
this.y = y;
}

@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}


}

-------------------------------------------------------------------------------------------

Triangle.java
-------------------------------------------------------------------------------------------
package org.aop.model;

import java.util.List;

public class Triangle {
private String name;
private List<Point> points;

public String getName() {
return name;
}

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

public List<Point> getPoints() {
return points;
}

public void setPoints(List<Point> points) {
this.points = points;
}

@Override
public String toString() {
return "Triangle [name=" + name + ", points=" + points + "]";
}


}

-------------------------------------------------------------------------------------------

spring.xml

Here we define bean definition to Point.java and add new attribute points type of List (Collection) to hold the three points.
We have defined a bean definition for each point.
When defining the collection or List attribute , we have used <list> tag and inside <list> tag we have given <ref>  tag to insert the values for the  list.
-------------------------------------------------------------------------------------------
<bean name="triangle" class="org.aop.model.Triangle">
<property name="name" value="Traingle name"></property>
<property name="points">
<list>
<ref bean="zeroPoint" />
<ref bean="pointTwo" />
<ref bean="pointThree" />
</list>
</property>
</bean>

<bean name="zeroPoint" class="org.aop.model.Point">
<property name="x" value="0"></property>
<property name="y" value="0"></property>
</bean>
<bean name="pointTwo" class="org.aop.model.Point">
<property name="x" value="20"></property>
<property name="y" value="0"></property>
</bean>
<bean name="pointThree" class="org.aop.model.Point">
<property name="x" value="0"></property>
<property name="y" value="20"></property>
</bean>

-------------------------------------------------------------------------------------------

Output
======================================================
Triangle [name=Traingle name, points=[Point [x=0, y=0], Point [x=20, y=0], Point [x=0, y=20]]]
======================================================

Spring Basic - Understanding scope and Alias

I have been using basic coding structure in explaining most of the concepts ,including AOP.
Below is the link
http://cgenit.blogspot.com/2015/03/aop-basic-application-code-and.html


Spring has basically 6 bean scopes and except for "singleton" and "prototype" other four are valid in the context of web-aware Spring ApplicationContext.

Following table shows the details

Table 5.3. Bean scopes
ScopeDescription
singleton(Default) Scopes a single bean definition to a single object instance per Spring IoC container.
prototypeScopes a single bean definition to any number of object instances.
requestScopes a single bean definition to the lifecycle of a single HTTP request; that is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
sessionScopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
global sessionScopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.
applicationScopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.

You can refer http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes   for more details.

Here I am going to explain the behavior of the singleton and the prototype.

Singleton -basically make sure there will be only once instance , in this case one instance per container.
Prototype - gives you a new instance in each time you request or refer the bean definition.

Remember : Spring container default configuration is "singleton"

Let's check it with application. we are using "ShapeService" bean definition to understand this.
We get the bean calling same definition twice and let's compare the two object.
If the result is true , then two object are similar --> mean Singleton.

xml definition for bean

spring.xml
----------------------------------------------------------------------------------------------------


<bean name="shapeService" class="org.aop.service.ShapeService"

autowire="byName" scope="singleton" id="shapeServiceId"></bean>

----------------------------------------------------------------------------------------------------

AppMain.java
----------------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);
ShapeService shapeService1 = ctx.getBean("shapeService",
ShapeService.class);



shapeService.getCircle();
System.out.println("shapeService and shapeService1 equal="
+ shapeService.equals(shapeService1));

}

}

----------------------------------------------------------------------------------------------------

output
===========================================================
shapeService and shapeService1 equal=true
===========================================================

Not : two objects are similar, Singleton

We can try with omitting the "singleton" scope definition. most of the time we write omitting this.
----------------------------------------------------------------------------------------------------
<bean name="shapeService" class="org.aop.service.ShapeService"

autowire="byName"  id="shapeServiceId"></bean>

----------------------------------------------------------------------------------------------------

output will be still same
===========================================================
shapeService and shapeService1 equal=true
===========================================================

Now let's change the scope to prototype and see the result.

----------------------------------------------------------------------------------------------------
<bean name="shapeService" class="org.aop.service.ShapeService"

autowire="byName" scope="prototype" id="shapeServiceId"></bean>

----------------------------------------------------------------------------------------------------

output resulting "false"
===========================================================
shapeService and shapeService1 equal=false
===========================================================

This is beacuse , prototype returns a new object for each call.


Now let's look at that with Alias.
Alias is referring same object with a different name. When we need create more than one bean from the same bean definition we can use Alias mechanism.

There are two ways to create alias
      1. we can give the alias names in the "name" attribute with space. comma or semicolon.
I have used space for my example.
     2.  use Alias tag

below is the sample bean definitions

spring.xml
----------------------------------------------------------------------------------------------------
<bean name="shapeService shapeService1 shapeService2" class="org.aop.service.ShapeService" autowire="byName" scope="singleton" id="shapeServiceId"></bean> <alias name="shapeService" alias="shapeServiceAlias" />


----------------------------------------------------------------------------------------------------

Here i have used singleton scope. That will help us to test and tell you that all beans are refer to one. When you compare with equal all must be equal.
We retrieve each bean and compare. Below is the test code and output.

AppMain .java
----------------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);
ShapeService shapeService1 = ctx.getBean("shapeService1",
ShapeService.class);
ShapeService shapeService2 = ctx.getBean("shapeService2",
ShapeService.class);
ShapeService shapeService3 = ctx.getBean("shapeServiceId",
ShapeService.class);
ShapeService shapeService4 = ctx.getBean("shapeServiceAlias",
ShapeService.class);

// FactoryService factoryService = new FactoryService();
// ShapeService shapeService = (ShapeService) factoryService
// .getBean("shapeService");

shapeService.getCircle();
System.out.println("shapeService and shapeService1 equal="
+ shapeService.equals(shapeService1));
System.out.println("shapeService and shapeService2 equal="
+ shapeService.equals(shapeService2));
System.out.println("shapeService and shapeServiceId equal="
+ shapeService.equals(shapeService3));
System.out.println("shapeService and shapeServiceAlias equal="
+ shapeService.equals(shapeService4));

}

}


----------------------------------------------------------------------------------------------------

Output :: Note ::all equal as all refer to one with singleton
===========================================================
shapeService and shapeService1 equal=true
shapeService and shapeService2 equal=true
shapeService and shapeServiceId equal=true
shapeService and shapeServiceAlias equal=true
===========================================================

So you can see the output being true as all refer to one bean definition and scope is singleton. Actually to test this we need to use the singleton scope as with prototype we cannot exactly tell it refers to same bean definition.
so we can see the output , if we change the scope to prototype.

spring.xml  Note:: scope change to prototype
----------------------------------------------------------------------------------------------------
<bean name="shapeService shapeService1 shapeService2" class="org.aop.service.ShapeService" autowire="byName" scope="prototype" id="shapeServiceId"></bean> <alias name="shapeService" alias="shapeServiceAlias" />

----------------------------------------------------------------------------------------------------

Output :: after change to prototype
===========================================================
shapeService and shapeService1 equal=false
shapeService and shapeService2 equal=false
shapeService and shapeServiceId equal=false
shapeService and shapeServiceAlias equal=false
===========================================================


all will be false as each time new instance will be created with the prototype scope.