0 Replies Latest reply on Oct 3, 2008 4:06 PM by Ryan Chapple

    RMI Invocation of Seam EJB causes dreaded "No Application Context" error

    Ryan Chapple Newbie

      So I have what seems to be a fairly straightforward proposition:  Have a client access a Seam-managed Session bean instance in the very traditional RMI fashion.  I create the InitialContext and get the remote reference to the bean without a problem, but as soon as I try to invoke one of the methods on the interface, it blows up.  It gives the error No application context active  


      Root Exception stack trace:
      java.lang.IllegalStateException: No application context active
              at org.jboss.seam.Component.forName(Component.java:1810)
              at org.jboss.seam.Component.getInstance(Component.java:1860)
              at org.jboss.seam.Component.getInstance(Component.java:1843)
              at org.jboss.seam.Component.getInstance(Component.java:1837)
              at com.allconnect.serviceability.beans.session.ServiceabilityManager<init>.(ServiceabilityManager.java:39)
              at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
              at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
              at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
              at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
              at org.jboss.ejb3.EJBContainer.construct(EJBContainer.java:514)
              at org.jboss.ejb3.AbstractPool.create(AbstractPool.java:66)
              at org.jboss.ejb3.InfinitePool.get(InfinitePool.java:49)
              at org.jboss.ejb3.ThreadlocalPool.create(ThreadlocalPool.java:50)
              at org.jboss.ejb3.ThreadlocalPool.get(ThreadlocalPool.java:90)
              at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:54)
              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      


      As I trace through the call with the debugger, I see that it's creating the component/EJB because the constructor is called, and the stack trace bears this out as well.  I've supposed that this could have something to do with the fact that a call like this doesn't go through the usual SeamInterceptor, so I've added an @Interceptors( SeamInterceptor.class ) annotation to the bean as well, but that didn't seem to help.


      I've seen other people talk about bootstrapping the Seam Lifecycle but I'm not sure what that would entail or how to go about that.  Any hints on that would be appreciated as well.


      Anyway, here's the EJB and the client code that's calling it, maybe more eyes would help me spot the Duh! part of the code.


      First, the bean:


      @Stateless
      @Scope( ScopeType.CONVERSATION )
      @Name( "serviceabilityManager" )
      @Interceptors( SeamInterceptor.class )
      
      public class ServiceabilityManager implements ServiceabilityManagerLocal, ServiceabilityManagerRemote
      {
          private ServiceabilityEngine serviceabilityEngine;
          private AddressNormalization addressEngine;
      
          public ServiceabilityManager()
          {
              serviceabilityEngine = (ServiceabilityEngine) Component.getInstance( "serviceabilityEngine" );
              addressEngine = (AddressNormalization) Component.getInstance( "addressNormalization" );
          }
      
          public Set<MarketItemBean> processRequest( String serviceAddress )
          {
              NormalizedAddressResults modifiedAddress;
      
              ServiceabilityEngine engine1 = getServiceabilityEngine();
              AddressNormalization engine0 = getAddressEngine();
      
              modifiedAddress = engine0.processAddress( serviceAddress );
              AddressBean processedAddress = modifiedAddress.getCorrectedAddress();
      
              Set<MarketItemBean> results = engine1.determineServiceability( processedAddress );
              return results;
          }
      
          public ServiceabilityEngine getServiceabilityEngine()
          {
              return serviceabilityEngine;
          }
      
          public void setServiceabilityEngine( final ServiceabilityEngine serviceabilityEngine )
          {
              this.serviceabilityEngine = serviceabilityEngine;
          }
      
          public AddressNormalization getAddressEngine()
          {
              return addressEngine;
          }
      
          public void setAddressEngine( final AddressNormalization addressEngine )
          {
              this.addressEngine = addressEngine;
          }
      
          public String echoBack( String message )
          {
              return "Here's your message back: " + message;
          }
      }



      Then the simple client:


      public class ServiceabilityService
      {
          private final String JNDI_PROPERTIES_PATH = "resources/jndi.properties";
          
          public String getServiceability(String inputAddress)
          {    
              InitialContext ctx = null;
              try
              {
                  Properties env =  new Properties();
                  env.load( new FileReader( JNDI_PROPERTIES_PATH ) );
                  ctx = new InitialContext( env );
                  ServiceabilityManagerRemote serviceMgr = 
                      (ServiceabilityManagerRemote) ctx.lookup( "serviceability/ServiceabilityManager/remote" );
                  
                  return serviceMgr.echoBack( inputAddress );
              }
              catch ( Exception e )
              {
                  e.printStackTrace();
              }
            
          }
          
      
      }



      Thanks in advance -- and at this point 'any' thoughts would be appreciated because I've run into a mental dead-end. 


      Cheers,
      Ryan