java - HASingleton 无法查找 JNDI bean

标签 java timer jboss

我正在尝试在 JBoss6.4 上部署 HASingleton。我已关注this教程提出以下内容:

我创建了一个服务,该服务应该通过 JNDI 注入(inject)计时器 bean 来启动计时器(自己的计时器接口(interface))。

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();
    }
}

计时器 bean、HATimerService 和 HATimerServiceActivator 都部署在名为 my-ear 的耳朵中。在日志文件中我可以看到:

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

但是,每隔一段时间(大约占所有部署的 1/3),此设置会由于 JNDI 查找失败的 NameNotFoundException 而失败。完整的异常是:引起:javax.naming.NameNotFoundException:查找 my-ear/my-module/MyTimer 时出错,服务服务 jboss.naming.context.java.global.my-ear.my-module.MyTimer 未启动

我的猜测是,这可能是某种竞争条件,其中 Bean 尚未在 JNDI 树中注册。如何让服务等待查找直到 bean 可用?

最佳答案

似乎有可能在部署单元上创建依赖关系。创建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是正确的依赖项,查找就会在bean启动后执行。

关于java - HASingleton 无法查找 JNDI bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38498057/

相关文章:

java - 是否可以重复倒数计时器?

java - WildFly 8.2 和 304 未修改

java - JBoss Cli - 查询返回可用方法

java - 忽略了 Wildfly 安全约束

父类(super class)上的 Java 泛型但并非所有子类都想定义类型参数

java - Eclipse 不适用于 java 8 和 win 8

java - Joda 日期时间格式化程序错误

java - (0)null 是什么类型的异常?

ios - 如何使用 objective-c 停止和启动应用程序委托(delegate)计时器?

c - 在 CCS 上使用端口中断和定时器