Java EJB在运行时修改计划属性值

时间:2014-04-08 09:09:40

标签: java reflection annotations ejb schedule

我在Java中有一个Singleton类,我有一个使用@Schedule注释的计时器。我希望在运行时更改Schedule的属性。以下是代码:

@Startup
@Singleton
public class Listener {

   public void setProperty() {
       Method[] methods = this.getClass().getDeclaredMethods();
       Method method = methods[0];
       Annotation[] annotations = method.getDeclaredAnnotations();
       Annotation annotation = annotations[0];
       if(annotation instanceof Schedule) {
            Schedule schedule = (Schedule) annotation;
            System.out.println(schedule.second());
       }
   }

    @PostConstruct
    public void runAtStartUp() {
         setProperty();
    }

   @Schedule(second = "3")
   public void run() {
       // do something
   }
}

我希望根据Property文件中的信息更改Schedule second运行时的值。这实际上是可能的吗? Property文件包含配置信息。我试图做@Schedule(second = SOME_VARIABLE),其中私有静态String SOME_VARIABLE = readFromConfigFile();这不起作用。它期望决赛具有恒定意义,我不想设定决赛。

我也看过这篇文章:Modifying annotation attribute value at runtime in java

它表明这是不可能的。

有什么想法吗?

编辑:

@Startup
@Singleton
public class Listener {
    javax.annotation.@Resource // the issue is this
    private javax.ejb.TimerService timerService;
    private static String SOME_VARIABLE = null;

    @PostConstruct
    public void runAtStartUp() {
         SOME_VARIABLE = readFromFile();
         timerService.createTimer(new Date(), TimeUnit.SECONDS.toMillis(Long.parse(SOME_VARIABLE)), null);
    }

    @Timeout
    public void check(Timer timer) {
        // some code runs every SOME_VARIABLE as seconds
    }
}

问题是使用@Resource注入。如何解决这个问题?

例外情况如下所示:

No EJBContainer provider available The following providers: org.glassfish.ejb.embedded.EJBContainerProviderImpl Returned null from createEJBContainer call
javax.ejb.EJBException
org.glassfish.ejb.embedded.EJBContainerProviderImpl
at javax.ejb.embeddable.EJBContainer.reportError(EJBContainer.java:186)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:121)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:78)

@BeforeClass
public void setUpClass() throws Exception {
    Container container = EJBContainer.createEJBContainer();
}

在使用Embeddable EJB Container进行单元测试期间会发生这种情况。一些Apache Maven代码位于此帖子:Java EJB JNDI Beans Lookup Failed

2 个答案:

答案 0 :(得分:0)

也许你可以使用TimerService。我已经编写了一些代码但是在我的Wildfly 8上它似乎运行了多次,即使它是一个Singleton。 文档http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html

希望这会有所帮助:

@javax.ejb.Singleton
@javax.ejb.Startup
public class VariableEjbTimer {

    @javax.annotation.Resource
    javax.ejb.TimerService timerService;

    @javax.annotation.PostConstruct
    public void runAtStartUp() {
        createTimer(2000L);
    }

    private void createTimer(long millis) {
        //timerService.createSingleActionTimer(millis, new javax.ejb.TimerConfig());
        timerService.createTimer(millis, millis, null);
    }

    @javax.ejb.Timeout
    public void run(javax.ejb.Timer timer) {
        long timeout = readFromConfigFile();
        System.out.println("Timeout in " + timeout);
        createTimer(timeout);
    }

    private long readFromConfigFile() {
        return new java.util.Random().nextInt(5) * 1000L;
    }
}

答案 1 :(得分:0)

我认为您正在寻找的解决方案已经讨论here

TomasZ是对的,你应该使用TimerService的程序化计时器,以适应你想要在运行时动态更改计划的情况。

相关问题