Jakarta ee 无法取消对EJB的@Asynchronous调用

Jakarta ee 无法取消对EJB的@Asynchronous调用,jakarta-ee,glassfish,ejb,java-ee-6,java-ee-7,Jakarta Ee,Glassfish,Ejb,Java Ee 6,Java Ee 7,在这个最简单的例子中,我做错了什么? (Glassfish 4.0-b87+Eclipse开普勒m6) java package com.example.cancelbug; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; i

在这个最简单的例子中,我做错了什么? (Glassfish 4.0-b87+Eclipse开普勒m6)

java

package com.example.cancelbug;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;

@Singleton
@Startup
public class Myself {
  @Inject Other other;
  private Future < Integer > future;

  @PostConstruct
  public void post_construct () {
    System.out.println("post_construct started");
    future = other.ton_of_work();
    System.out.println("post_construct ended");
  }

  @PreDestroy
  public void pre_destroy () {
    System.out.println("pre_destroy started");
    System.out.println("cancel result: " + Boolean.toString(future.cancel(true)));
    try {
      System.out.println("future result: " + future.get().toString());
    } catch (InterruptedException | ExecutionException e) {
      System.out.println("future result: interrupted");
      Thread.currentThread().interrupt();
      System.out.println("thread reinterrupted");
    }
    System.out.println("pre_destroy ended");
  }
}
package com.example.cancelbug;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.Future;
导入javax.annotation.PostConstruct;
导入javax.annotation.PreDestroy;
导入javax.ejb.Singleton;
导入javax.ejb.Startup;
导入javax.inject.inject;
@独生子女
@启动
我自己也上公共课{
@注射其他药物;
私人期货<整数>期货;
@施工后
公共无效后构造(){
System.out.println(“启动后构造”);
未来=其他.吨的工作();
System.out.println(“后期构造结束”);
}
@发情前期
公共无效预销毁(){
System.out.println(“预销毁启动”);
System.out.println(“取消结果:+Boolean.toString(future.cancel(true)));
试一试{
System.out.println(“未来结果:+future.get().toString());
}捕获(中断异常|执行异常e){
System.out.println(“未来结果:中断”);
Thread.currentThread().interrupt();
System.out.println(“线程重新中断”);
}
System.out.println(“预销毁结束”);
}
}
Other.java

package com.example.cancelbug;

import java.util.concurrent.Future;

import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;

@Stateless
public class Other {
  @Asynchronous
  public Future < Integer > ton_of_work () {
    System.out.println("other: ton_of_work started");
    int i;
    for (i = 0; i < 10; ++i) {
      try {
        System.out.println("other: take a nap");
        Thread.sleep(1000L);
        System.out.println("other: woke up: " + Integer.toString(i));
      } catch (InterruptedException e) {
        System.out.println("other: ton_of_work interrupted");
        Thread.currentThread().interrupt();
        break;
      }
    }
    System.out.println("other: ton_of_work returning");
    return new AsyncResult < Integer >(new Integer(i));
  }
}
package com.example.cancelbug;
导入java.util.concurrent.Future;
导入javax.ejb.AsyncResult;
导入javax.ejb.Asynchronous;
导入javax.ejb.Stateless;
@无国籍
公共类其他{
@异步的
公共未来工作量(){
System.out.println(“其他:已开始的工作量”);
int i;
对于(i=0;i<10;++i){
试一试{
System.out.println(“其他:小睡”);
睡眠(1000L);
System.out.println(“其他:唤醒:“+Integer.toString(i));
}捕捉(中断异常e){
System.out.println(“其他:工作量中断”);
Thread.currentThread().interrupt();
打破
}
}
System.out.println(“其他:吨工作返回”);
返回新的AsyncResult(新的整数(i));
}
}
输出

post_construct started
post_construct ended
other: ton_of_work started
other: take a nap
other: woke up: 0
other: take a nap
other: woke up: 1
other: take a nap
other: woke up: 2
other: take a nap
pre_destroy started
cancel result: false            <<<<<<< expected true; ton_of_work: interrupted
other: woke up: 3               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 4               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 5               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 6               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 7               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 8               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 9               <<<<<<< expected no such output
other: ton_of_work returning
future result: 10               <<<<<<< expected 2
pre_destroy ended
post_构造已启动
后期构造结束
其他:已开始大量工作
其他:小睡一会儿
其他:醒来时间:0
其他:小睡一会儿
其他:醒来:1
其他:小睡一会儿
其他:醒来:2
其他:小睡一会儿
预销毁已开始

取消结果:falseEJB3.1仅提供协作异步中断;也就是说,EJB可以检查客户端是否调用了cancel。即使调用Future.cancel(true),也无法获取实际的Thread.interrupt


有一个开放的EJB规范问题()允许实际的线程中断。EJB3.2专家组(,,,)对此进行了讨论,但讨论最终推迟到了EJB规范的下一个版本。

injection
@Resource SessionContext session\u context
和调用
session\u context.wascanceCalled()
会返回
true
,但它不会中断
睡眠
或其他阻塞调用,因此让应用程序逻辑也足够频繁地轮询状态是一件痛苦的事情。
post_construct started
post_construct ended
other: ton_of_work started
other: take a nap
other: woke up: 0
other: take a nap
other: woke up: 1
other: take a nap
other: woke up: 2
other: take a nap
pre_destroy started
cancel result: true             <<<<<<< actual false
other: ton_of_work interrupted  <<<<<<< actual missing
other: ton_of_work returning
future result: 2                <<<<<<< actual 10
pre_destroy ended