Announcement Announcement Module
Collapse
No announcement yet.
Spring EJB's do not failover automatically Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring EJB's do not failover automatically

    Hi all,
    My program uses Spring to connect to EJB's hosted on JBoss. The EJB's on JBoss are clustered. In the Spring's configuration file, I have provided the list of JBoss IP addresses and HA-JNDI Port numbers, for the Spring beans to access. When the program starts, it connects to which ever JBoss it finds first that is up and is available. If the Jboss is brought down, the bean does not automatically failover to another JBoss node even though the IP of the JBoss is provided in the list of url's. Below is the definition of one of the beans ..
    <bean id="oneBean" class="org.springframework.jndi.JndiObjectFactoryB ean">
    <property name="jndiName" value="sample/oneBean/remote"/>
    <property name="expectedType" value="sample.OneBeanIntf"/>
    <property name="jndiEnvironment">
    <props>
    <prop key="java.naming.factory.initial">
    org.jnp.interfaces.NamingContextFactory</prop>
    <prop key="java.naming.factory.url.pkgs">
    org.jboss.naming:org.jnp.interfaces</prop>
    <prop key="java.naming.provider.url">
    jnp://3.63.62.90:1200,jnp://3.63.2.22:1200</prop>
    </props>
    </property>
    </bean>

    Has anybody faced this problem before ?

  • #2
    What is the type of the object? Looking at the source code, your defintion should return what a normal JNDI lookup would return, which in this case would probably be a remote reference to your EJB that you can make invocations on.

    What thing that JndiObjectFactoryBean does different than a straight JNDI lookup: it caches the object. So multiple calls to your ApplicationContext will always return the same JNDI object.

    Can you try a test program doing the lookup by hand and see if that can do the failover properly? I'd be surprised if the problem is the JndiObjectFactoryBean, but this test could help eliminate that possibility.

    Comment


    • #3
      Hi ,
      Thanks for your reply, I have written a sample program, for testing if it is a problem with Spring configuration or with JBoss configuration.
      public class FailoverTest {
      public static void main(String args[]){
      Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY,
      "org.jnp.interfaces.NamingContextFactory");
      env.put(Context.PROVIDER_URL, "jnp://3.63.62.9:1200,jnp://3.63.20.22:1200");
      try{
      Context initialContext = new InitialContext(env);
      while(true)
      System.out.println(initialContext.lookup("sample/beanOne"));
      }
      catch(Exception ex)
      {
      System.out.println(ex.getMessage());
      }
      }

      This peice of code does a perfect failover. What can be the possible problem with the Spring configuration or with JndiObjectFactoryBean?

      Comment


      • #4
        When posting code please use [ code][/code ] tags. Also understand what is happening and realize that your testcase isn't the same as what spring does.

        You iterate numerous times over a lookup, ie retrieve a new bean each time. Spring only retrieves ones and caches the result. So it does only 1 lookup and then caches the object. You can disable this by setting cache to false, then it will do a lookup before calling a method. Mind you this affects performance!

        If you use EJBs you also might want to check to EJB classes spring provides which provide more flexibility/configurability for EJB stuff. You can for instance configure if it should retrieve a new instance of an exception occurs.

        Comment


        • #5
          Spring and EJB's do not failover

          Thanks for the reply ! Is there any link where I can find examples for these configurations ?? I tried setting
          Code:
          <bean id="oneBean" class="org.springframework.jndi.JndiObjectFactoryBean">
          <property name="jndiName" value="sample/oneBean/remote"/>
          <property name="expectedType" value="sample.OneBeanIntf"/>
          <property name="cache" value="false">
          <property name="jndiEnvironment">
          <props>
          <prop key="java.naming.factory.initial">
          org.jnp.interfaces.NamingContextFactory</prop>
          <prop key="java.naming.factory.url.pkgs">
          org.jboss.namingrg.jnp.interfaces</prop>
          <prop key="java.naming.provider.url">
          jnp://3.63.62.90:1200,jnp://3.63.2.22:1200</prop>
          </props>
          </property>
          </bean>
          cache to false but still it does not work . Some other way so that performance is not impacted ?

          Thanks in advance
          Last edited by sonali.majumdar; May 26th, 2008, 02:45 PM.

          Comment


          • #6
            The reference guide is quite clear on how to use EJB's with Spring. Check the relevant chapter. Chapter 18 is the one to read, that contains a lot of samples.

            Comment


            • #7
              Spring EJB's do not failover automatically

              Hi! Thanks again ! I tried out the following code , a very crude way of doing it . Is there a better solution ?
              Code:
              public class FailoverTest {
              public static void main(String args[]){
              ApplicationContext ctx = new ClassPathXmlApplicationContext("contextFailover1.xml");
              				try{
              while(true){
              System.out.println("first "+ctx.getBean("sample/oneBean"));
              }
              }catch(Exception ex){
              System.out.println(ex.getMessage());
              ApplicationContext ctx2 =  new ClassPathXmlApplicationContext("contextFailover2.xml");
              System.out.println("Failover "+ ctx2.getBean("sample/oneBean"));
              }
              }
              }
              Thanks !

              Comment


              • #8
                Not sure what you are trying to test here... So it is hard to tell. If you use ejb's and use the EJB ProxyFactoryBeans from spring then spring will handle all the failover/reconnection stuff for you. You have to use the EJB ProxyFactoryBeans for that and not the simpler JndiObjectFactoryBean.

                Comment


                • #9
                  Spring EJB's do not failover automatically

                  Yeah, Thanks again ! I am trying failover logic in Spring .but I am in Spring 2.0.6 and using EJB3 . I read in the post
                  that SimpleRemoteStatelessSessionProxyFactoryBean support for EJB3 is included in Spring 2.5.1 . Any suggestions ?

                  Comment


                  • #10
                    Upgrade .

                    There isn't much you can do with the JndiObjectFactoryBean in the regard of failover. The only thing you can do is disable the lookupOnStartup and the caching so that a new instance will always be retrieved. But that isn't failover.

                    If you cannot upgrade for some reason, you might want to extend the JndiObjectFactoryBean yourself and create one that has some failover capability. You might want to take a look at the EJB stuff (from 2.5) on how it is done.

                    Comment


                    • #11
                      Failover in EJB cluster is done on the cluster-aware stub level, not on the client Spring level. The list of servers you defined in your config is used only for jndi-lookup failover, and has nothing to do with failover once the lookup is done.

                      Jndi lookup of clustered ejbs will get you a home object that's aware of clustering environment and each remote method invocation will refresh the list of cluster nodes that are available in the cluster at the moment. So - if your ejbs are not configured for clustering, no amount of client-side configuration fiddling will help you.

                      Comment


                      • #12
                        Spring EJB's do not failover automatically

                        Hey, Thanks a ton ! I solved the problem finally . Upgraded to Spring 2.5.5 and used jee-jndi lookup .

                        Comment


                        • #13
                          Could you explain in detail how your problem was resolved? I am running into a similar problem but have not upgraded to 2.5.1.

                          Comment


                          • #14
                            EJB's do not failover automatically

                            Hi,
                            I had a set of EJB's on the server side and used Spring to look up the EJB's from the client side. The problem was if the stub was being downloaded from one m/c, automatic failover to another m/c would not happen even though Spring had all the addresses. The problem is the JNDITargetFactorybean is a simple bean which does a simple JNDI look up. Also, the EJB's should be clustered.

                            Comment


                            • #15
                              configuring the reconnect time on failover

                              Hi,
                              I am using the jee-jndi tag foe failover between servers as following:
                              Code:
                              <jee:jndi-lookup id="sampleBean"
                                           jndi-name="ejb/sampleBean/remote"
                                           cache="true"
                                           resource-ref="true"
                                           lookup-on-startup="true"
                                           expected-type="com.sampleBean">
                                           <jee:environment>
                                  	java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
                                   	java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
                                     	java.naming.provider.url=jnp://3.62.33.24:1099, jnp://3.45.23.23:1099
                                  </jee:environment>
                                </jee:jndi-lookup>
                              The time for failover between two servers is quite high. Even though the failover happens eventually. Is there some way , I can configure the time for failover ? Somewhere the minimum. maximum or the default is specified ?

                              Thanks,

                              Comment

                              Working...
                              X