First Hello World example in Spring framework by using DI.

Hi Friend when you going start learn Spring Framework you will start to write first Hello World Program
Below is step by step to write first program

1. Write the applicationContext.xml (bean container)

<?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:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
      http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-2.5.xsd
     http://www.springframework.org/schema/util
     http://www.springframework.org/schema/util/spring-util-2.5.xsd"
     xmlns:context="http://www.springframework.org/schema/context">
<context:annotation-config/>
<context:component-scan base-package="com.dao"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="cal" class="com.test.calculation" init-method="init">
<property name="name" value="kumud"></property>
</bean>
</beans>

2. Write bean class for calculation

package com.test;
import org.springframework.beans.factory.BeanNameAware;
public class calculation  implements BeanNameAware{
    public String name = null;
    public String getName() {
        return this.name;
    }
    public void init() {
        System.out.println("Inside the init methos");
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setBeanName(String arg0) {
        System.out.println("setting the bean name ********************");
    }
}

3. write TestClass

package com.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestClass {
    public static void main(String [] args)
    {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        calculation calc=(calculation)ctx.getBean("cal");
        System.out.println("The name of is"+calc.getName());
        }

}

Core concept of Comparable and Comparator interface in Java | interview question on Java collection

package com.rajeev;


1. By Using comparable interface sorting logic(compareTo(Object obj)) implements within the class
so every time when you want to change sorting logic then there must be change inside the class. suppose
in below code right now sorting logic is based on employee's name when you want to changed it to based on employee Id then you
need to change logic as below

 @Override
       public int compareTo(Object obj) {
              emplyee emp=(emplyee)obj;
             return Integer.toString(this.employeeId).compareTo(Integer.toString(emp.getEmployeeId()));
       }

import java.util.*;
import java.util.Iterator;
import java.util.TreeSet;
class emplyee implements Comparable

{
       String name;
       int employeeId;
       public emplyee(String name, int employeeId )
       {
              this.name=name;
              this.employeeId=employeeId;
       }
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       public int getEmployeeId() {
              return employeeId;
       }
       public void setEmployeeId(int employeeId) {
              this.employeeId = employeeId;
       }
        public int compareTo(Object obj) {
              emplyee emp=(emplyee)obj;
             return this.name.compareTo(emp.getName());
       }
       /*@Override
       public int compareTo(Object obj) {
              emplyee emp=(emplyee)obj;
             return Integer.toString(this.employeeId).compareTo(Integer.toString(emp.getEmployeeId()));
       }*/
}
public class comparableTest {
       public static void main(String [] args)
       {
              TreeSet ts= new TreeSet();
              ts.add(new emplyee("Humud",800));
              ts.add(new emplyee("rajeev",600));
              ts.add(new emplyee("aalu",100));
              //ts.add("rajeev");
              //ts.add("Aalu");
              Iterator it =ts.iterator();
              while(it.hasNext())
              {
                     emplyee em=(emplyee)it.next();
                     System.out.println("SOrted -------"+em.getName());
              }
       }
}


2. By Using Comparator interface you have to write to your sorting logic outside the
   class . so when you want change the sorting logic not need to change logic inside the emplyee class

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

class nameComparator implements Comparator
{
       @Override
       public int compare(Object obj1, Object obj2) {
              emplyee emp=(emplyee)obj1;
              emplyee emp2=(emplyee)obj2;
              return Integer.toString(emp.employeeId).compareTo(Integer.toString(emp2.getEmployeeId()));
       }
}
class emplyeeIdComparator implements Comparator
{
       @Override
       public int compare(Object obj1, Object obj2) {
              emplyee emp=(emplyee)obj1;
              emplyee emp2=(emplyee)obj2;
              return emp.getName().compareTo(emp2.getName());
       }
}
class emplyee
{
       String name;
       int employeeId;
       public emplyee(String name, int employeeId )
       {
              this.name=name;
              this.employeeId=employeeId;

       }
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       public int getEmployeeId() {
              return employeeId;
       }
       public void setEmployeeId(int employeeId) {
              this.employeeId = employeeId;
       }
       /*@Override
       public int compareTo(Object obj) {
              emplyee emp=(emplyee)obj;
              return Integer.toString(this.employeeId).compareTo(Integer.toString(emp.getEmployeeId()));
       }*/
}
public class comparableTest {
       public static void main(String [] args)
       {
              TreeSet ts= new TreeSet(new emplyeeIdComparator());
              ts.add(new emplyee("Rumud",800));
              ts.add(new emplyee("rajeev",600));
              ts.add(new emplyee("aalu",100));
              //ts.add("rajeev");
              //ts.add("Aalu");
              Iterator it =ts.iterator();
              while(it.hasNext())
              {
                     emplyee em=(emplyee)it.next();
                     System.out.println("SOrted -------"+em.getName());
              }

       }
}



How To create Cron Job in Hybris e-commerce suite | Interview Question on Hybris 4.8 e-commerce suite

Below given step by step to create hybris cron job

1. create a class MyFirstCronJob as below

/**
*
 */
package se.hm.core.cronjob;

import de.hybris.platform.cronjob.enums.CronJobResult;
import de.hybris.platform.cronjob.enums.CronJobStatus;
import de.hybris.platform.cronjob.model.CronJobModel;
import de.hybris.platform.servicelayer.cronjob.AbstractJobPerformable;
import de.hybris.platform.servicelayer.cronjob.PerformResult;


/**
* @author
 *
 */
public class TestCronJob extends AbstractJobPerformable
{

                /*
                * (non-Javadoc)
                *
                 * @see
                * de.hybris.platform.servicelayer.cronjob.AbstractJobPerformable#perform(de.hybris.platform.cronjob.model.CronJobModel
                * )
                */
                private String exportDir;

                /**
                * @return the exportDir
                */
                public String getExportDir()
                {
                                return exportDir;
                }

                /**
                * @param exportDir
                *           the exportDir to set
                */
                public void setExportDir(final String exportDir)
                {
                                this.exportDir = exportDir;
                }



                @Override
                public PerformResult perform(final CronJobModel arg0)
                {
                                System.out.printlnTestCronJob Job Started");


                                System.out.printlnTestCronJob Job Finished");
                                return new PerformResult(CronJobResult.SUCCESS, CronJobStatus.FINISHED);
                }

}


2. After create  KumudJob.java register this cron job in xml as below

<bean id="myFirstCrobJob" class="se.hm.core.cronjob.TestCronJob" scope="tenant"
                                  parent="abstractJobPerformable">
                                  <property name="exportDir" ref="exportDataBaseDirectory"/>
                </bean>

3. Now Run UPDATE Hybris

4. After UPDATE your created Cron job  KumudJob  will show in list of cronjob in Hmc where you can schedule .

How to Write Own Caching in Java | Improve your Java application Performance By Using Cache

Caching is very important when you want to improve your Java application performance
In My Project there was some performance issue during show huge date in screen. In that case
i have improve my java application performance by written own Cache Utility class, Which is below

public class UtilCache
{
 private UtilCache(String cacheName, int sizeLimit, int maxInMemory, long expireTimeMillis, boolean useSoftReference, boolean useFileSystemStore, String propName, String... propNames) {
        this.name = cacheName;
        this.sizeLimit = sizeLimit;
        this.maxInMemory = maxInMemory;
        this.expireTimeNanos = TimeUnit.NANOSECONDS.convert(expireTimeMillis, TimeUnit.MILLISECONDS);
        this.useSoftReference = useSoftReference;
        this.useFileSystemStore = useFileSystemStore;
        setPropertiesParams(propName);
        setPropertiesParams(propNames);
        int maxMemSize = this.maxInMemory;
        if (maxMemSize == 0) maxMemSize = sizeLimit;
        if (maxMemSize == 0) {
            memoryTable = new ConcurrentHashMap<Object, CacheLine<V>>();
        } else {
            memoryTable = new Builder<Object, CacheLine<V>>()
            .maximumWeightedCapacity(maxMemSize)
            .listener(this)
            .build();
        }
        if (this.useFileSystemStore) {
            // create the manager the first time it is needed
            jdbmMgr = fileManagers.get(fileStore);
            if (jdbmMgr == null) {
                Debug.logImportant("Creating file system cache store for cache with name: " + cacheName, module);
                try {
                    String ofbizHome = System.getProperty("ofbiz.home");
                    if (ofbizHome == null) {
                        Debug.logError("No ofbiz.home property set in environment", module);
                    } else {
                        jdbmMgr = new JdbmRecordManager(ofbizHome + "/" + fileStore);
                    }
                } catch (IOException e) {
                    Debug.logError(e, "Error creating file system cache store for cache with name: " + cacheName, module);
                }
                fileManagers.putIfAbsent(fileStore, jdbmMgr);
            }
            jdbmMgr = fileManagers.get(fileStore);
            if (jdbmMgr != null) {
                try {
                    this.fileTable = HTree.createInstance(jdbmMgr);
                    jdbmMgr.setNamedObject(cacheName, this.fileTable.getRecid());
                    jdbmMgr.commit();
                } catch (IOException e) {
                    Debug.logError(e, module);
                }
            }
        }
    }

    private static String getNextDefaultIndex(String cacheName) {
        AtomicInteger curInd = defaultIndices.get(cacheName);
        if (curInd == null) {
            defaultIndices.putIfAbsent(cacheName, new AtomicInteger(0));
            curInd = defaultIndices.get(cacheName);
        }
        int i = curInd.getAndIncrement();
        return i == 0 ? "" : Integer.toString(i);
    }

    public static String getPropertyParam(ResourceBundle res, String[] propNames, String parameter) {
        try {
            for (String propName: propNames) {
            if(res.containsKey(propName+ '.' + parameter)) {
                try {
                return res.getString(propName + '.' + parameter);
                } catch (MissingResourceException e) {}
            }
            }
            // don't need this, just return null
            //if (value == null) {
            //    throw new MissingResourceException("Can't find resource for bundle", res.getClass().getName(), Arrays.asList(propNames) + "." + parameter);
            //}
        } catch (Exception e) {
            Debug.logWarning(e, "Error getting " + parameter + " value from cache.properties file for propNames: " + propNames, module);
        }
        return null;
    }

    protected void setPropertiesParams(String cacheName) {
        setPropertiesParams(new String[] {cacheName});
    }

    public void setPropertiesParams(String[] propNames) {
        ResourceBundle res = ResourceBundle.getBundle("cache");

        if (res != null) {
            String value = getPropertyParam(res, propNames, "maxSize");
            if (UtilValidate.isNotEmpty(value)) {
                this.sizeLimit = Integer.parseInt(value);
            }
            value = getPropertyParam(res, propNames, "maxInMemory");
            if (UtilValidate.isNotEmpty(value)) {
                this.maxInMemory = Integer.parseInt(value);
            }
            value = getPropertyParam(res, propNames, "expireTime");
            if (UtilValidate.isNotEmpty(value)) {
                this.expireTimeNanos = TimeUnit.NANOSECONDS.convert(Long.parseLong(value), TimeUnit.MILLISECONDS);
            }
            value = getPropertyParam(res, propNames, "useSoftReference");
            if (value != null) {
                useSoftReference = "true".equals(value);
            }
            value = getPropertyParam(res, propNames, "useFileSystemStore");
            if (value != null) {
                useFileSystemStore = "true".equals(value);
            }
            value = getPropertyParam(res, new String[0], "cache.file.store");
            if (value != null) {
                fileStore = value;
            }
        }
    }

    private Object fromKey(Object key) {
        return key == null ? ObjectType.NULL : key;
    }

    @SuppressWarnings("unchecked")
    private K toKey(Object key) {
        return key == ObjectType.NULL ? null : (K) key;
    }

    private void addAllFileTableKeys(Set<Object> keys) throws IOException {
        FastIterator<Object> iter = fileTable.keys();
        Object key = null;
        while ((key = iter.next()) != null) {
            keys.add(key);
        }
    }

    public Object getCacheLineTable() {
        throw new UnsupportedOperationException();
    }

    public boolean isEmpty() {
        if (fileTable != null) {
            try {
                synchronized (this) {
                    return fileTable.keys().next() == null;
                }
            } catch (IOException e) {
                Debug.logError(e, module);
                return false;
            }
        } else {
            return memoryTable.isEmpty();
        }
    }

    /** Puts or loads the passed element into the cache
     * @param key The key for the element, used to reference it in the hastables and LRU linked list
     * @param value The value of the element
     */
    public V put(K key, V value) {
        return putInternal(key, value, expireTimeNanos);
    }

    public V putIfAbsent(K key, V value) {
        return putIfAbsentInternal(key, value, expireTimeNanos);
    }

    CacheLine<V> createSoftRefCacheLine(final Object key, V value, long loadTimeNanos, long expireTimeNanos) {
        return tryRegister(loadTimeNanos, new SoftRefCacheLine<V>(value, loadTimeNanos, expireTimeNanos) {
            @Override
            CacheLine<V> changeLine(boolean useSoftReference, long expireTimeNanos) {
                if (useSoftReference) {
                    if (differentExpireTime(expireTimeNanos)) {
                        return this;
                    } else {
                        return createSoftRefCacheLine(key, getValue(), loadTimeNanos, expireTimeNanos);
                    }
                } else {
                    return createHardRefCacheLine(key, getValue(), loadTimeNanos, expireTimeNanos);
                }
            }

            @Override
            void remove() {
                removeInternal(key, this);
            }
        });
    }

    CacheLine<V> createHardRefCacheLine(final Object key, V value, long loadTimeNanos, long expireTimeNanos) {
        return tryRegister(loadTimeNanos, new HardRefCacheLine<V>(value, loadTimeNanos, expireTimeNanos) {
            @Override
            CacheLine<V> changeLine(boolean useSoftReference, long expireTimeNanos) {
                if (useSoftReference) {
                    return createSoftRefCacheLine(key, getValue(), loadTimeNanos, expireTimeNanos);
                } else {
                    if (differentExpireTime(expireTimeNanos)) {
                        return this;
                    } else {
                        return createHardRefCacheLine(key, getValue(), loadTimeNanos, expireTimeNanos);
                    }
                }
            }

            @Override
            void remove() {
                removeInternal(key, this);
            }
        });
    }

    private CacheLine<V> tryRegister(long loadTimeNanos, CacheLine<V> line) {
        if (loadTimeNanos > 0) {
            ExecutionPool.addPulse(line);
        }
        return line;
    }

    private CacheLine<V> createCacheLine(K key, V value, long expireTimeNanos) {
        long loadTimeNanos = expireTimeNanos > 0 ? System.nanoTime() : 0;
        if (useSoftReference) {
            return createSoftRefCacheLine(key, value, loadTimeNanos, expireTimeNanos);
        } else {
            return createHardRefCacheLine(key, value, loadTimeNanos, expireTimeNanos);
        }
    }
    private V cancel(CacheLine<V> line) {
        // FIXME: this is a race condition, the item could expire
        // between the time it is replaced, and it is cancelled
        V oldValue = line.getValue();
        ExecutionPool.removePulse(line);
        line.cancel();
        return oldValue;
    }

    /** Puts or loads the passed element into the cache
     * @param key The key for the element, used to reference it in the hastables and LRU linked list
     * @param value The value of the element
     * @param expireTimeMillis how long to keep this key in the cache
     */
    public V put(K key, V value, long expireTimeMillis) {
        return putInternal(key, value, TimeUnit.NANOSECONDS.convert(expireTimeMillis, TimeUnit.MILLISECONDS));
    }

    public V putIfAbsent(K key, V value, long expireTimeMillis) {
        return putIfAbsentInternal(key, value, TimeUnit.NANOSECONDS.convert(expireTimeMillis, TimeUnit.MILLISECONDS));
    }

    V putInternal(K key, V value, long expireTimeNanos) {
        Object nulledKey = fromKey(key);
        CacheLine<V> oldCacheLine = memoryTable.put(nulledKey, createCacheLine(key, value, expireTimeNanos));
        V oldValue = oldCacheLine == null ? null : cancel(oldCacheLine);
        if (fileTable != null) {
            try {
                synchronized (this) {
                    if (oldValue == null) oldValue = fileTable.get(nulledKey);
                    fileTable.put(nulledKey, value);
                    jdbmMgr.commit();
                }
            } catch (IOException e) {
                Debug.logError(e, module);
            }
        }
        if (oldValue == null) {
            noteAddition(key, value);
            return null;
        } else {
            noteUpdate(key, value, oldValue);
            return oldValue;
        }
    }


}

Create WSDL in Apache obfiz | Create web services in Apache ofbiz | Apache ofbiz web services tutorial.

In my project there is requirement of web services integration with Microsoft BizTalk i.e. Through WSDL
Biztalk will communicate with Apache ofbiz Services.

Following below step to follow for exposed ofbiz service to as web Services

1. Create a Apache ofbiz Services as below
   package org.ofbiz.party.party;

import java.util.Map;

import javolution.util.FastMap;

import org.ofbiz.service.DispatchContext;

public class TestWebService {
   
   
      public static Map<String, Object> testWebSerice(DispatchContext ctx, Map<String, ? extends Object> context) {
         
          Map<String, Object> result = FastMap.newInstance();
        try
        {
          String username=(String) context.get("userName");
         
          if(username.equals("kumud"))
          {
              result.put("returnMsg", "Hi Kumud") ;
          }
          else
          {
              result.put("returnMsg", "You are not kumud") ;
          }
         
          return result;
         
      }
     
      catch(Exception ex)
      {
          ex.fillInStackTrace();
          result.put("returnMsg", "Hi Kumud") ;
          return result;
      }
}
}


2. Register service in services.xml file as below

 <service name="TestWebSerice" engine="java" auth="false"
            location="org.ofbiz.party.party.TestWebService" invoke="testWebSerice"  export="false">
        <description>Test Web Service  by kumud</description>
       
        <attribute name="userName" type="String" mode="IN" optional="false"/>
        <attribute name="returnMsg" type="String" mode="OUT" optional="false"/>
       
    </service>

3. For expose above service as Web Services by making  export="true" in above configuration

   <service name="TestWebSerice" engine="java" auth="false"
            location="org.ofbiz.party.party.TestWebService" invoke="testWebSerice"  export="true">
        <description>Test Web Service  by kumud</description>
       
        <attribute name="userName" type="String" mode="IN" optional="false"/>
        <attribute name="returnMsg" type="String" mode="OUT" optional="false"/>
       
    </service>
   
4. Now start server hit by url http://localhost:8080/webtools/control/SOAPService/TestWebSerice?wsdl in web browser
   there show WSDL file

difference between return; and return (xx); in Java | Java concept

java return keyword is one of the most frequently used keyword in java and also one of the concept, which most programmers say they are well aware of. But, I still meet programmers who say that they are little confused when they come down to return statement. Especially with respect to the method which has void as their return type. So, this post would help you in clearing those doubts and help you understand the clear picture of it... in the most simplest way.
We all know that Java return keyword is used to return the control back to calling method with a certain data-type which was promised during the method declaration. As many wanted to know if we can use just the return keyword(like this: return;) but not return any value(like this: return obj;), then I have to say yes to that. Se the below java programs which will help you understanding the difference better,

public class ReturnTypes {
    public static void main(String args[]){
        functionVoid();
       
functionType();
    }
   
    public static int
functionType(){
        return 1;
    }

    private static void
functionVoid() {
        System.out.println("1");
        if(true){
            return;
        }
        // return;  // This line if UnCommented, would result in Compilation error
        System.out.println("2");
    }
}

If you see in the method functionType() the return keyword is used to return an primitive int value, which is quiet normal and know to almost every java programmer.

But, If you see the method functionVoid() it in fact uses the controversial return keyword(just "return;") which doesn't return anything at-all. Yes this is absolutely valid to use it that way... Ahaaaa hold on, I am not yet done completely... and now imagine if you can use the same return type outside the scope of if statement, as It's already available in program but commented out... That will certainly thorough you an compilation error.

Now why so.. There is nothing wrong with the syntax of return; statement but the error is something different as the compiler is just complaining about "Unreachable Code"... 

By now you know that we can use both of these conventions and are very much valid. But you can ask yourself a question on why actually java needs a return; statement in the first, when we already know that the method is not meant to return any thing back to the calling function as we have declared it void...??

The answer is, you can treat return keyword as a form of goto statement. As it will directly move the control to the line where the method is called. And if you want to accomplish that in an void method then what other option you have to do that other than return; statement.

How string comparison works in java | Java interview question for experinced developer

explain "how String comparison works in Java?" is the most common question interviewers ask these days, and today this post is going to explain the answer in detail. String is one of Java's most admired feature and most used class in the whole Java for sure and I hope you all won't deny that fact. But, sadly most programmers fail to answer this question. Reason is either learners or programmers don't take String seriously or they just don't take Java seriously. So, let's start our learning.....

There are two thing into consideration when we talk about String comparison
1. "==" normal Java comparison operator
2. ".equals()" method of Object class

"=="  in Java is used to compare two values, when I say values... I mean, they can be of any primitive types or any object types. Now when our focus is specifically on String class, we take objects alone into consideration. So, what really happens when you compare any two objects using == operator..? It's simple.. They just compare the two objects and see if they both are pointing to same memory location. If Java found that both strings are pointing to same memory location, then it returns boolean true else if both objects are pointing to different memory locations then it returns boolean false. Now, at this point of time don't worry about the implementation as I will explain with example in detail.

".equals()" in Java on the other hand is actually used to compare the contents of two objects. When I say contents of the objects, I mean value within the string and not the memory location to which the objects point to. In this kind of comparison if Java finds that the value in two different string objects are same, they return boolean true else boolean false. As simple as that isn't it..! Just give this below example a try in your favorite editor,

public class StringTestOne {
    public static void main(String[] args) {
        String s1 = "AAA";
        String s2 = "AAA";
        String s3 = "BBB";
       
        if(s1==s2){
            System.out.println("s1 == s2 : TRUE");
        } else {
            System.out.println("s1 == s2 : FALSE");
        }
        if(s1.equals(s2)){
            System.out.println("s1.equals(s2) : TRUE");
        } else {
            System.out.println("s1.equals(s2) : FALSE");
        }
       
        if(s1==s3){
            System.out.println("s1 == s3 : TRUE");
        } else {
            System.out.println("s1 == s3 : FALSE");
        }
        if(s1.equals(s3)){
            System.out.println("s1.equals(s3) : TRUE");
        } else {
            System.out.println("s1.equals(s3) : FALSE");
        }
    }
}
now let us trace the program,

-first the fourth if statement : it is resulting FALSE as we know that .equals() method compares the content of two object i.e "AAA" and "BBB"(no human on earth can prove that "AAA" is equal to "BBB"),  thus it's very clear that it has returned FALSE.

-then the third if statement : it returns FALSE as again we know that == operator will compare the memory location to which the objects s1 and s3 refers to, but not the values . As of now it makes sense that Java would create a separate memory location for every object created on heap. Thus, even in this case Java would have created two different objects s1 and s3 which would be pointing to two different memory places in memory. So, expected result FALSE. hmmm  you are smart..!

-then the second if statement : again as expected the values of s1 and s2 are same and hence the .equals() method will and should return TRUE.

-Now comes the first if statement : Why on earth is it returning TRUE while there are two different object s1 and s2 into consideration. Yes I agree to the point that they both have same values, but Java needs to compare the object handles while using == operator... isn't it what wee have learned till now..? Yes very much true and that's the reason we have this post today. 

This TRUE thing in the first if statement is due to the concept of  String class being immutable. You might have certainly learned in you college that your professors saying String is immutable. That's the reason Strings are so special in Java and that's the reason why few programmers still feel String comparison a confusing task. Don't worry as it would be explained clearly now, 

Internally Java uses the concept of String pool in order to make use of strings  efficiently across Java. Thus, whenever you create new string objects in your program, it will first search that string pool to see if there is any existing string value which is already created having same value. And if Java thinks that an value already exists in pool, then it takes no permission from you(as string is already final and programmer has no control on it) to point your new string object to the same memory location to which earlier object was pointing to. If it thinks there is not such value in the pool, they make a new entry into the pool. Let's take the earlier examples,

String s1 = "AAA"; //This will first search the String pool to see if there is any such value already existing in the pool. Knowing that there is no such string value, it will add the value into Java's String pool for the first time and assigns the memory location to object handle s1.
String s2 = "AAA"; //This will also first search the String pool to see if there is any such entry in the pool with the value "AAA", As you it finds one such entry it will just make use of that memory location and assigns the same to string object s2 as well.

Which means that, even though we have two objects s1 and s2 created, Java has done some internal optimization to ensure that it doesn't waste memory unnecessarily and thus s1 and s2 will be pointing to the same memory location where the value "AAA" is actually stored. That is the reason why we got TRUE in the first if statement earlier. And that is the reason why string is called immutable.