2016-07-21 32 views
1

我想在JBoss6.4上部署HASingleton。我遵循this教程提出以下幾點:HASingleton無法查找JNDI bean

我創建一個服務,應該通過JNDI注入定時器bean來啓動一個定時器(自己的定時器接口)。

public class HATimerService implements Service<String> { 
    private Logger logger = Logger.getLogger(HATimerService.class); 

    private final AtomicBoolean started = new AtomicBoolean(false); 
    private ServiceName serviceName; 
    private final InjectedValue<ServerEnvironment> env = new InjectedValue(); 

    private String JNDI = "java:global/my-ear/my-module/MyTimer" 

    public HATimerService() { 
     serviceName = ServiceName.JBOSS.append(new String[]{"my", "ha", "singleton", "MyHaService"}); 
    } 

    public String getValue() throws IllegalStateException, IllegalArgumentException { 
     return ""; 
    } 

    public void start(StartContext context) throws StartException { 
     if(!started.compareAndSet(false, true)) { 
      throw new StartException("The service is still started!"); 
     } else { 
      try { 
       InitialContext e = new InitialContext(); 
       TimerScheduler myTimer = (TimerScheduler)e.lookup(JNDI); 
       timer.startTimer(); 

      } catch (NamingException var6) { 
       throw new StartException("Could not initialize timer", var6); 
      } 
     } 
    } 

    public void stop(StopContext context) { 
     if(started.compareAndSet(true, false)) { 
      try { 
       InitialContext e = new InitialContext(); 
       ((TimerScheduler)e.lookup(JNDI)).stopTimer(); 
      } catch (NamingException var4) { 
       logger.error("Could not stop timer", var4); 
      } 
     } 

    } 

    public ServiceName getServiceName() { 
     return serviceName; 
    } 

    public InjectedValue<ServerEnvironment> getEnvironment() { 
     return env; 
    } 
} 

我也有一個激活器來激活服務。

public class HATimerServiceActivator implements ServiceActivator { 
    private final Logger log = Logger.getLogger(this.getClass()); 

    public HATimerServiceActivator() { 
    } 

    public void activate(ServiceActivatorContext context) { 
      HATimerService service = new HATimerService(); 
      this.log.info(service.getServiceName() + "HATimerService will be installed"); 

      SingletonService singleton = new SingletonService(service, service.getServiceName()); 
      singleton.build(new DelegatingServiceContainer(context.getServiceTarget(), context.getServiceRegistry())) 
        .addDependency(ServerEnvironmentService.SERVICE_NAME, ServerEnvironment.class, service.getEnvironment()) 
        .setInitialMode(Mode.ACTIVE) 
        .install(); 
    } 
} 

定時器豆,HATimerService和HATimerServiceActivator都部署在名爲my-ear耳朵。在日誌文件中我可以看到:

JNDI bindings for session bean named MyTimer.... : 
java:global/my-ear/my-module/MyTimer 

然而,每過一段時間(約1/3都展開時的),這種設置由於NameNotFoundException在JNDI查找失敗失敗。完全的例外是:Caused by: javax.naming.NameNotFoundException: Error looking up my-ear/my-module/MyTimer, service service jboss.naming.context.java.global.my-ear.my-module.MyTimer is not started

我的猜測是,這可能是某種競爭條件,其中bean尚未註冊到JNDI樹中。如何讓服務等待查找,直到bean可用?

回答

0

似乎有可能在部署單元上創建依賴關係。當創建SingletonService,以下依賴可加:

ServiceName ejbDependency = ServiceName.of("jboss", "deployment", "subunit", "my-ear.ear", "my-module.jar", "component", "MyTimerBean", "START"); 
singleton.build(new DelegatingServiceContainer(context.getServiceTarget(), context.getServiceRegistry())) 
       .addDependency(ServerEnvironmentService.SERVICE_NAME, ServerEnvironment.class, service.getEnvironment()) 
       .setInitialMode(Mode.ACTIVE) 
       .addDependency(ejbDependency) 
       .install(); 

只要ejbDependency是一個正確的依賴關係,查找將豆開始之後進行。