‏הצגת רשומות עם תוויות spring. הצג את כל הרשומות
‏הצגת רשומות עם תוויות spring. הצג את כל הרשומות

יום שלישי, 6 במאי 2014

Spring inheritance tree

With Spring you can collect classes and there inherits tree into list .
For an example :
Use the autowire spring context declaration:
@Configuration
@ComponentScan("com.model.cars")
public class SpringContext {
}

We can declare a ctor in a @component Road class
 @Autowired
public Road(List<Car> pCar) {
 
}
The auto wired process scans the  com.model.cars directory for all the components that inherit from Car class (and the car class itself if exists in the scanning directory )  and construct the car Ctor parameter pCar list accordingly .
So if the com.model.cars path contains the following component
@Component
Class sosita extends Car
and
@Component
Class Subaru extends
sosita
The  Road ctor will be called with a 2 items list of sosita and Subaru

Reference:
http://lkrnac.net/blog/2014/04/30/load-inheritance-tree/

יום חמישי, 27 ביוני 2013

Write and read from mongodb using spring integration

I extend the spring integration demo:Samples (Basic) – MongoDb and add a read capabilities to the MongoDbOutboundAdapterDemo class.

The spring context

  1: <?xml version="1.0" encoding="UTF-8"?>
  2: <beans xmlns="http://www.springframework.org/schema/beans"
  3:   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4:   xmlns:int="http://www.springframework.org/schema/integration"
  5:   xmlns:int-mongodb="http://www.springframework.org/schema/integration/mongodb"
  6:   xmlns:mongo="http://www.springframework.org/schema/data/mongo"
  7:         xmlns:beans="http://www.springframework.org/schema/beans"
  8:   xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd
  9:     http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.2.xsd
 10:     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 11:                 http://www.springframework.org/schema/integration/mongodb http://www.springframework.org/schema/integration/mongodb/spring-integration-mongodb-2.2.xsd">
 12: 
 13:   <mongo:db-factory id="mongoDbFactory" dbname="test"/>
 14: 
 15:   <int-mongodb:outbound-channel-adapter id="deafultAdapter" />
 16:       
 17:   <int-mongodb:outbound-channel-adapter id="adapterWithConverter" mongo-converter="stringConverter"/>
 18: 
 19:   <int-mongodb:inbound-channel-adapter id="simpleInboundAdapter" channel="outputChannel" 
 20:                        query="{address.state : 'CA'}">    
 21:             <int:poller fixed-rate="1000" max-messages-per-poll="1"/>
 22:   </int-mongodb:inbound-channel-adapter>
 23: 
 24:     <int:publish-subscribe-channel id="outputChannel">
 25:     </int:publish-subscribe-channel>
 26:  </beans>
 27: 

 The code


  1: package org.springframework.integration.samples.mongodb.outbound;
  2: 
  3: import org.springframework.context.ApplicationContext;
  4: import org.springframework.context.support.FileSystemXmlApplicationContext;
  5: import org.springframework.integration.Message;
  6: import org.springframework.integration.MessageChannel;
  7: import org.springframework.integration.core.MessageHandler;
  8: import org.springframework.integration.core.SubscribableChannel;
  9: import org.springframework.integration.message.GenericMessage;
 10: import org.springframework.integration.samples.mongodb.domain.Address;
 11: import org.springframework.integration.samples.mongodb.domain.Person;
 12: import org.springframework.integration.samples.mongodb.util.DemoUtils;
 13: /**
 14: *
 15: * @author of the orginal source Oleg Zhurakousky
 16: * @Add reading Zvika Peer 
 17: */
 18: public class MongoDbOutboundAdapterDemo {
 19: 
 20: 
 21:   public static void main(String[] args) throws Exception {
 22:     DemoUtils.prepareMongoFactory(); // will clean up MOngoDb
 23:     new MongoDbOutboundAdapterDemo().runDefaultAdapter();
 24:   }
 25: 
 26:   public void runDefaultAdapter() throws Exception {
 27: 
 28:                 ApplicationContext context  =
 29:         new FileSystemXmlApplicationContext(
 30:                 "C:\\learn\\spring\\integration\\samples\\basic\\mongodb\\src\\main\\java\\org\\springframework\\integration\\samples\\mongodb\\outbound\\mongodb-out-config.xml"
 31:                         );
 32:                         
 33:       MessageChannel messageChannel = context.getBean("deafultAdapter", MessageChannel.class);
 34:       messageChannel.send(new GenericMessage<Person>(this.createPersonA()));
 35:       messageChannel.send(new GenericMessage<Person>(this.createPersonB()));
 36:       messageChannel.send(new GenericMessage<Person>(this.createPersonC()));
 37: 
 38:              SubscribableChannel outputChannel = context.getBean("outputChannel", SubscribableChannel.class);
 39: 
 40:             outputChannel.subscribe(new MessageHandler()
 41:             {
 42:                 @Override
 43:                 public void handleMessage(Message<?> msg)
 44:                 {
 45:                    System.out.println("==> HelloWorldDemo Async message: " + msg.getPayload());
 46:                 }
 47:             });
 48:                 
 49:               Thread.sleep(4000);
 50:             System.out.println("Finished");
 51:         }
 52:   }

The result
Finished
==> HelloWorldDemo Async message: [{ "_id" : { "$oid" : "51c945b3fe3a5df7ab5f7a3d"} , "_class" : "org.springframework.integration.samples.mongodb.domain.Person" , "fname" : "John" , "lname" : "Doe" , "address" : { "street" : "3401 Hillview Ave" , "city" : "Palo Alto" , "zip" : "94304" , "state" : "CA"}}, { "_id" : { "$oid" : "51c945b3fe3a5df7ab5f7a3e"} , "_class" : "org.springframework.integration.samples.mongodb.domain.Person" , "fname" : "Josh" , "lname" : "Doe" , "address" : { "street" : "123 Main st" , "city" : "San Francisco" , "zip" : "94115" , "state" : "CA"}}]


Resources:
http://static.springsource.org/spring-integration/reference/html/mongodb.html

יום שישי, 7 ביוני 2013

Create an executable jar using maven

I found several resources about how to make an executable jar using maven.
I want the the executable jar file to contain all the dependencies jars that the project need .
In general the following steps are used to generate the jar file:
Create the sample eclipse project :

  1: $ mvn archetype:generate -DgroupId=my.learn -DartifactId=mavenToExeJar -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
  2: 
  3: cd mavenToExeJar
  4: 
  5: mvn eclipse:eclipse

The main class:

  1: package my.learn;
  2: import org.springframework.context.ApplicationContext;
  3: import org.springframework.context.support.FileSystemXmlApplicationContext;
  4: public class App 
  5: {
  6:     public static void main( String[] args )
  7:     {     
  8:          ApplicationContext context = new FileSystemXmlApplicationContext(
  9:         "SpringXMLConfig.xml");
 10:          MyBean theMyBean = (MyBean) context.getBean("MyBean");
 11:        System.out.println( "Hello:" + theMyBean.getName() );
 12:     }
 13: }
 14: 

The bean :

  1: package my.learn;
  2: public class MyBean {
  3:   private String mName;
  4:   
  5:   public String getName()
  6:   {
  7:     return mName;    
  8:   }
  9:   public void setName(String pValue)
 10:   {
 11:      mName = pValue;
 12:   }  
 13: }


The spring context file

  1: <?xml version="1.0" encoding="windows-1252"?>
  2: <beans xmlns="http://www.springframework.org/schema/beans"
  3:        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4:        xmlns:aop="http://www.springframework.org/schema/aop"
  5:        xmlns:c="http://www.springframework.org/schema/c"
  6:        xmlns:context="http://www.springframework.org/schema/context"
  7:        xmlns:flow="http://www.springframework.org/schema/webflow-config"
  8:        xmlns:jms="http://www.springframework.org/schema/jms"
  9:        xmlns:lang="http://www.springframework.org/schema/lang"
 10:        xmlns:p="http://www.springframework.org/schema/p"
 11:        xmlns:tx="http://www.springframework.org/schema/tx"
 12:        xmlns:util="http://www.springframework.org/schema/util"
 13: 
 14:        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 15:           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
 16:           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
 17:           http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
 18:           http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.2.xsd
 19:           http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.2.xsd
 20:           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
 21:           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
 22: ">
 23:     <bean id="MyBean" class="my.learn.MyBean">
 24:     <property name="name" value="Abdala" />
 25:   </bean>
 26: </beans>

The maven xml pom file :

  1:  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2: xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  3: <modelVersion>4.0.0</modelVersion>
  4: <groupId>my.learn</groupId>
  5: <artifactId>mavenToExeJar</artifactId>
  6: <packaging>jar</packaging>
  7: <version>1.0-SNAPSHOT</version>
  8: <name>mavenToExeJar</name>
  9: <url>http://maven.apache.org</url>
 10: <properties>
 11:             <jdk.version>1.6</jdk.version>
 12:  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 13:     </properties>
 14: <dependencies>
 15: <dependency>
 16:   <groupId>junit</groupId>
 17:   <artifactId>junit</artifactId>
 18:   <version>3.8.1</version>
 19:   <scope>test</scope>
 20: </dependency>
 21: 
 22:             <!-- Spring framework -->
 23:             <dependency>
 24:              <groupId>org.springframework</groupId>
 25:              <artifactId>spring-context</artifactId>
 26:              <version>3.2.3.RELEASE</version>
 27:             </dependency> 
 28: </dependencies>
 29:    <build>
 30:        <plugins>
 31:            <plugin>
 32:                <groupId>org.apache.maven.plugins</groupId>
 33:                <artifactId>maven-jar-plugin</artifactId>
 34:                   <version>2.3</version>
 35:                      <configuration>
 36:                          <archive>
 37:                              <manifest>
 38:                                  <mainClass>my.learn.App</mainClass>
 39:                                    <addClasspath>true</addClasspath>
 40:                              </manifest>
 41:                          </archive>
 42:                      </configuration>
 43:            </plugin>
 44:            <plugin>
 45:                <groupId>org.dstovall</groupId>
 46:                <artifactId>onejar-maven-plugin</artifactId>
 47:                <version>1.4.4-SNAPSHOT</version>
 48:                <executions>
 49:                    <execution>
 50:                        <configuration>
 51:                            <!-- Optional 
 52:                            <onejarVersion>0.97</onejarVersion>
 53:                            Optional, use only if you need to include native libraries(dll's)
 54:                            <directory>${project.build.directory}/dllextract</directory>
 55:                            <include>test.dll</include>
 56:                        </includes>
 57:                    </fileSet>
 58:                </binlibs>-->
 59:                <!-- Optional, default is false -->
 60:                <attachToBuild>true</attachToBuild>
 61:                <!-- Optional, default is "onejar" -->
 62:                <classifier>onejar</classifier>
 63:                        </configuration>
 64:                        <goals>
 65:                            <goal>one-jar</goal>
 66:                        </goals>
 67:                    </execution>
 68:                </executions>
 69:            </plugin>
 70:        </plugins>
 71:    </build>
 72: 
 73:          <pluginRepositories>
 74:              <pluginRepository>
 75:                  <id>onejar-maven-plugin.googlecode.com</id>
 76:                  <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo-snapshot</url>
 77:              </pluginRepository>
 78:          </pluginRepositories>
 79:   </project>
 80:  

The folder structure
Capture29
After compiling the project :
mvn compiler:compile etc
The packing stage :
mvn package
creates the  executable jar file. (don't forget to copy the spring context file to the right location )


Execute the jar file
C:\learn\java\maven\executableJar\mavenToExeJar\target>java -jar mavenToExeJar-1
.0-SNAPSHOT.one-jar.jar


and walla :
Jun 08, 2013 10:18:22 AM org.springframework.context.support.AbstractApplication
Context prepareRefresh
INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationCon
text@16fdac: startup date [Sat Jun 08 10:18:22 IDT 2013]; root of context hierar
chy
Jun 08, 2013 10:18:22 AM org.springframework.beans.factory.xml.XmlBeanDefinition
Reader loadBeanDefinitions
INFO: Loading XML bean definitions from file [C:\learn\java\maven\executableJar\
mavenToExeJar\target\SpringXMLConfig.xml]
Jun 08, 2013 10:18:22 AM org.springframework.beans.factory.support.DefaultListab
leBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.
DefaultListableBeanFactory@7588c: defining beans [MyBean]; root of factory hiera
rchy
Hello:Abdalla


Resources:
http://www.mkyong.com/maven/how-to-create-a-jar-file-with-maven/
http://one-jar.sourceforge.net/

ApplicationContext loading

There is two ways to load application context xml file  in spring: classpathxmlapplicationcontext or filesystemxmlapplicationcontext.

FileSystemXmlApplicationContext:
Loads the application context acoording to a full path for an example 

  1: ApplicationContext context = new FileSystemXmlApplicationContext(
  2:    "I:\\Learn\\java\\maven\\executableJar\\mavenToExeJar\\SpringXMLConfig.xml");

The current path can be obtained by :


  1:   final String dir = System.getProperty("user.dir");
  2:         System.out.println("current dir = " + dir);

classpathxmlapplicationcontext
The spring application context should be in the CLASSPATH
Getting the current class path can be done  by:


  1: String theClassPath = System.getProperty("java.class.path");
  2: System.out.println("theClassPath dir = " + theClassPath);
  3: 

An example for using classpathxmlapplicationcontext :


  1: ApplicationContext context = new ClassPathXmlApplicationContext (
  2:         "SpringXMLConfig.xml");

Resources
http://en.wikipedia.org/wiki/Classpath_(Java)
http://codeissue.com/issues/i84e1f376448bef/classpathxmlapplicationcontext-vs-filesystemxmlapplicationcontext

יום חמישי, 6 ביוני 2013

Sprint Context File is packed to

When creating an executable jar of spring project
Capture27
The jar packing procedure may pack the spring context file as well.
So the jar file will contain the file and the program that use spring will load the context from the context file in the jar bundle.
The context file / files should be exclude from the jar in order to allow the configurability  and deploy to the jar directory before executing the jar .

יום שישי, 24 במאי 2013

Custom scope in spring

Spring frameworks enabled extending its  objects creation scopes by allowing to add custom scope to the system.
I have found this capacity very use full in enterprise system when I wants to access the same object from application  layers that doesn’t share the same spring context.(Every layer construct its own spring application context and get the same bean.

 Capture12 

In order to make an object instance available to all the system the solution used to store its state in a cache.When the spring frame work is trying to retrieve an object that is declared with the Enterprise scope it try to find if the object exists in the cache if yes it retrieve the object from the cache and return it .If the object doen’t exists in the cache the scope creates the instance store it in the cache and return it .

In order to implement the custom scope we need to implement the org.springframework.beans.factory.config.Scope interface.
The most important method to override is the  get method .
A sample scope implementation :

package javaapplicationbasicspring;
import org.springframework.beans.factory.ObjectFactory;
import java.util.HashMap;

public class myCustomScop implements org.springframework.beans.factory.config.Scope
{
    static HashMap<String , Object> mObjectCache;
   
    public myCustomScop()
    {
        mObjectCache = new HashMap<>();
    }

    @Override
    public Object get(String string, ObjectFactory<?> of) {
        if (mObjectCache.containsKey(string))
        {
            return mObjectCache.get(string);
        }
     
       Object theSingletonObject = of.getObject();
      
       mObjectCache.put(string, theSingletonObject);
      
       return theSingletonObject;
    }

    @Override
    public Object remove(String string) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void registerDestructionCallback(String string, Runnable r) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public Object resolveContextualObject(String string) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public String getConversationId() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

The of.getObject(); construct and update an object .
The bean definition:

package javaapplicationbasicspring;
public class SimpleAccountService {
 
   private String mString;
   private SimpleAccountService mParent;  

   private String mTestValue = "Nothing";

    public String getTestValue() {
        return mTestValue;
    }

    public void setTestValue(String mTestValue) {
        this.mTestValue = mTestValue;
    }
          
    public SimpleAccountService()
    {
    }
}
The spring context xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:lang="http://www.springframework.org/schema/lang"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
          http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd
">
    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="Enterprise">
    <map>
    <entry key="Enterprise">
    <bean class="javaapplicationbasicspring.myCustomScop"/>
    </entry>
    </map>
    </property>
</bean>

    <bean id="accountService" class="javaapplicationbasicspring.SimpleAccountService" scope="Enterprise">
        <property name="Value">
            <value>Hello Zvika</value>
        </property>
    </bean>
</beans>

The test case :
ClassPathXmlApplicationContext appContextParent = new ClassPathXmlApplicationContext(
                new String[] {"resources/ParentSpringXMLConfig.xml"}  );
      
ClassPathXmlApplicationContext appContextParent2 = new ClassPathXmlApplicationContext(
                new String[] {"resources/ParentSpringXMLConfig.xml"}  );

SimpleAccountService theSimpleAccountService =
                (SimpleAccountService)appContextParent2.getBea("accountService");
          
SimpleAccountService theSimpleAccountService2 =
                (SimpleAccountService)appContextParent.getBean("accountService");
   
theSimpleAccountService.setTestValue ("Zvika");
System.out.print ("Hello: " + theSimpleAccountService2.getTestValue());

and the result is :
Hello: Zvika





 







יום שלישי, 14 במאי 2013

Spring context scope

The spring Ioc container is not singleton .every call to ClassPathXmlApplicationContext  generate a separate spring Ioc  context .

Lets define the following spring bean :

<bean id="accountService" class="javaapplicationbasicspring.SimpleAccountService" scope="singleton">
</bean>

(I know scope="singleton” is the default context)

The SimpleAccountService class has one property :

private String mTestValue = "Nothing";

public String getTestValue() {
return mTestValue;
}

public void setTestValue(String mTestValue) {
this.mTestValue = mTestValue;

Lets do the following text :

ClassPathXmlApplicationContext appContextParent = new ClassPathXmlApplicationContext(
new String[] {"resources/ParentSpringXMLConfig.xml"});

ClassPathXmlApplicationContext appContextParent2 = new ClassPathXmlApplicationContext(
new String[] {"resources/ParentSpringXMLConfig.xml"} );

SimpleAccountService theSimpleAccountService =
(SimpleAccountService)appContextParent2.getBean("accountService");

SimpleAccountService theSimpleAccountService2 =
(SimpleAccountService)appContextParent.getBean("accountService");

theSimpleAccountService.setTestValue ("Zvika");

System.out.print ("Hello: " + theSimpleAccountService2.getTestValue())



The result is :


Hello: Nothing


we saw that each application context has its one instance .


I don't like it because an application should take care of managing the single spring context in it deferent layers , modules etc instead of taking care by the spring infrastructure .

יום שני, 13 במאי 2013

About spring integration Hello world sample

The Hello world demo construct a simple  integration graph:

Capture4 

Where the message enter the input channel processed by the service activator and exit form the output Chanel .

The declaration in the spring integration descriptor xml:

<beans:beans xmlns="http://www.springframework.org/schema/integration"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/integration
   http://www.springframework.org/schema/integration/spring-integration.xsd">

    <channel id="inputChannel"/>

    <channel id="outputChannel">
        <queue capacity="10"/>
    </channel>

    <service-activator input-channel="inputChannel"
                           output-channel="outputChannel"
                           ref="helloService"
                           method="sayHello"/>

    <beans:bean id="helloService" class="org.springframework.integration.samples.helloworld.HelloService"/>

</beans:beans>

Note that the output channel is declared with a queue of 10 messages allowed to be stored before consuming .

The code for using the integration graph:

The pojo Hello service :

public class HelloService
{

public String sayHello(String name) {
return "Hello " + name;
}
}



The input and the output channels reference:


AbstractApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/spring/integration/helloWorldDemo.xml", HelloWorldApp.class);
MessageChannel inputChannel = context.getBean("inputChannel", MessageChannel.class);
PollableChannel outputChannel = context.getBean("outputChannel", PollableChannel.class);





Lets try to send 14 messages behind the output channel capacity :


for ( int i= 1 ; i < 14 ; i ++)
{
  logger.info("Sending no:" + Integer.toString (i));
  inputChannel.send(new GenericMessage<String>("Mr no" + Integer.toString (i)));
}


The application stack waiting for the output channel to be consumed:


08:35:01.874 INFO  [main][org.springframework.integration.samples.helloworld.HelloWorldApp] Sending no:9
08:35:01.875 INFO  [main][org.springframework.integration.samples.helloworld.HelloWorldApp] Sending no:10
08:35:01.875 INFO  [main][org.springframework.integration.samples.helloworld.HelloWorldApp] Sending no:11


Trying to receive the message in endless loop :


 
while (true)
{
Message theMessage = outputChannel.receive(0);
logger.info("==> HelloWorldDemo: " + theMessage.getPayload());
}



cause a java.lang.NullPointerException when the output channel queue gets empty .


In the next post I will consume the message async in order to void the stacking of the sender and the null exception in the receiver channel.