标签: cdi

使用Jersey 2.1和CDI

我尝试使用Jersey 2.1,并CDI在我的Java EE 7项目,该项目被部署在Glassfish 4.0.

Jersey模块依赖于Guava库.但是使用带有CDI的Guava库(14.0.1)会导致抛出以下异常.

CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [Set<Service>] with qualifiers [@Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject com.google.common.util.concurrent.ServiceManager(Set<Service>)].
Run Code Online (Sandbox Code Playgroud)

我怎样才能克服这个问题?

glassfish jersey java-ee guava cdi

6
推荐指数
1
解决办法
1568
查看次数

Java EE 中的 CDI - 哪些 Java 类不能注入?

我正在阅读Oracle Java EE 6 教程和“Beans as Injectable Objects”部分下,它说

可以注入以下类型的对象:

(几乎)任何 Java 类

会话豆......

无法注入的 Java 类的示例是什么?这只是他们提到的一些理论上的技术限制,还是可以注入的类有已知的限制?

java cdi jakarta-ee

6
推荐指数
1
解决办法
2337
查看次数

CDI可以将标准库POJO注入EJB吗?

我可以将自己的POJO注入到这样的托管对象中:

import javax.ejb.Stateless;
import javax.inject.Inject;
@Stateless
public class SomeEjb {
    @Inject
    private SomePojo somePojo;
}
Run Code Online (Sandbox Code Playgroud)

我有这个POJO:

// No annotations
public class SomePojo {   
}
Run Code Online (Sandbox Code Playgroud)

这很好用.如果我将EJB注入JSF支持bean,我可以看到值somePojo是非空值,如预期的那样.

但是,如果我尝试注入java.util.DateSomeEjb,我得到部署以下异常:

Severe: Exception while loading the app : WELD-001408 Unsatisfied dependencies for type [Date] with qualifiers [@Default] at injection point [[field] @Inject private SomeEjb.date]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Date] with qualifiers [@Default] at injection point [[field] @Inject private SomeEjb.date]
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:311)
Run Code Online (Sandbox Code Playgroud)

SomeEjb现在:

// No annotations
public class …
Run Code Online (Sandbox Code Playgroud)

java ejb cdi

6
推荐指数
1
解决办法
1749
查看次数

CDI 对话 Bean - BusyConversationException

我有一个会话范围的 bean ComponenteM,它被注入到请求范围的 bean ComponenteC 中。

@Named
@RequestScoped
public class ComponenteC implements Serializable {
    @Inject
    ComponenteM componenteM;
}
Run Code Online (Sandbox Code Playgroud)


ComponenteC 有一个由 HtmlCommandLink(以编程方式创建)调用的导出方法。导出方法调用与 SAP BO 网络服务集成的网络服务,以便将报表导出到 excel。但是,只有当调用时间过长时,我才会收到 BusyConversationException。任何其他少于 10 分钟的导出都是成功的。
同时我在对话中没有其他电话(AJAX 或非 AJAX 调用)。我已经尝试在开始对话时为对话 bean 设置显式超时,但我读到它仅用作对 CDI 容器的建议,并且可能会被忽略:

public void beginConversation() {
    if (conversation.isTransient()) {
        conversation.setTimeout(60 * 60 * 1000);
        conversation.begin();
    }
}
Run Code Online (Sandbox Code Playgroud)


错误是:
ServletException.org.jboss.weld.context.BusyConversationException 的根本原因:WELD-000322 对话锁定超时:1

我还尝试通过线程发出导出请求,然后将导出的文档返回到对话中。我的想法是让一个线程忙于处理文档和 componenteC 的导出,在等待线程完成时,偶尔会检查执行 componenteM.beginConversation();


我试图理解为什么即使没有并发请求也会抛出 BusyConversationException。
谢谢你。

cdi conversation-scope weld

6
推荐指数
1
解决办法
3218
查看次数

将请求范围数据传递给 CDI 中的异步方法

Java EE 7 应用程序在 Wildfly 9.0.2.Final 上运行。从@Asynchronous 方法中访问请求范围的数据存在问题。

在 Web 过滤器中,数据(例如令牌)被设置到 RequestScoped CDI bean 中。稍后我们要访问这些数据。如果我们在一个线程中工作,则一切正常。但是如果需要异步运行代码,就会出现问题。CDI 注入空 bean,请求数据丢失。

这是示例:

@RequestScoped
public class CurrentUserService implements Serializable {
  public String token;
}

@Stateless
public class Service {
   @Inject
   private RestClient client;

    @Resource
    private ManagedExecutorService executorService;

    @Resource
    private ContextService contextService;

    @Asynchronous
    private <T> Future<T> getFuture(Supplier<T> supplier) {
        Callable<T> task = supplier::get;
        Callable<T> callable = contextService.createContextualProxy(task, Callable.class);
        return executorService.submit(callable);
    }

   public String getToken() throws Exception {
      return getFuture(client::getToken).get();
   }
}

@ApplicationScoped
public class RestClient { …
Run Code Online (Sandbox Code Playgroud)

java asynchronous cdi java-ee-7 wildfly

6
推荐指数
1
解决办法
4369
查看次数

如果bean是Java EE 7(CDI 1.1)中的EJB bean,则injectPoint.getBean()返回null

我想从producer方法获取bean以读取其属性.在某些情况下,bean是一个EJB Singletonbean.

我简化了我的代码以专注于这个问题.

我的简单限定符:

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface InjectMe {}
Run Code Online (Sandbox Code Playgroud)

简单生产者:

@Dependent
public class SimpleProducer {

    @Produces
    @InjectMe
    public String getInjectMe(InjectionPoint ip) {
        // ip.getBean() returns null for some reason   
        return "ip=" + ip + ", bean=" + ip.getBean();
    }
}
Run Code Online (Sandbox Code Playgroud)

EJB(Singleton):

@Singleton
@Startup
public class SimpleSingleton {

    @Inject
    @InjectMe
    private String injectMe;

    @PostConstruct
    public void init() {
        System.out.println(injectMe);
   }
Run Code Online (Sandbox Code Playgroud)

}

控制台输出:

信息:ip = [BackedAnnotatedField] @Inject @InjectMe private com.test.ejb.SimpleSingleton.injectMe, bean=null

当我将Singletonbean 更改为 …

cdi ejb-3.1 glassfish-4 java-ee-7

6
推荐指数
1
解决办法
729
查看次数

在ResourceContext initResource创建的JAX-RS子资源实例中无法进行CDI注入

我有一个JAX-RS资源类,它使用@Context ResourceContext为子资源类提供路径路由,为每种资源类型创建子资源实例.在此示例中,我将实例化报告子资源.

资源

@Context
ResourceContext rc;

@Path("reports")
public ReportsResource reportsResource() {
    return rc.initResource(new ReportsResource());
}
Run Code Online (Sandbox Code Playgroud)

子资源需要一个ReportService类的实例(使用@Stateless注释定义),自然的解决方案是@Inject it ...

报告SubResource

@Inject
ReportsService rs;

@GET
@Path("{rptno}")
@Produces(MediaType.APPLICATION_XML)
public Report report(@PathParam("rptno") int rptNumber) throws Exception {
    return rs.getReport(rptNumber);
}
Run Code Online (Sandbox Code Playgroud)

我将Glass EE7与Glassfish和WAS Liberty Profile一起使用的经验是,不会注入ReportService rs的实例,而是将rs保留为null并导致NPE.

我的假设是因为资源类正在执行"新的ReportsResource()",所以CDI无法查看ReportsResource实例,因此ReportsResource不是容器管理的.这似乎是与通过ResourceContext获取子资源时将EJB注入JAX-RS 2.0子资源的问题相同的情况

我的解决方案有所不同,我在Resource类中选择@Inject ReportService,然后在ReportsResource构造函数上传递实例.

修改资源

@Inject
ReportsSerivce rs;

@Context
ResourceContext rc;

@Path("reports")
public ReportsResource reportsResource() {
    return rc.initResource(new ReportsResource(rs));
}
Run Code Online (Sandbox Code Playgroud)

修改报告子资源

public class ReportsResource {
    private ReportsSerivce rs;

    public ReportsResource(ReportsSerivce rs) {
      this.rs = rs;
    }

    @Context …
Run Code Online (Sandbox Code Playgroud)

java rest dependency-injection java-ee cdi

6
推荐指数
1
解决办法
2735
查看次数

带有@Produces注释但无范围的方法的行为

我有一个带@Produces注释的方法可以创建一个Apple.

当我@ApplicationScoped像这样使用它

public class AppleProducer {
    @ApplicationScoped
    @Produces
    public Apple createApple() {
        return new Apple();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后Apple只为整个应用程序创建一次.

当我@RequestScoped像这样使用它

public class AppleProducer {
    @RequestScoped
    @Produces
    public Apple createApple() {
        return new Apple();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后它会为每个请求创建.

但是,如果我没有指定范围怎么办?

public class AppleProducer {
    @Produces
    public Apple createApple() {
        return new Apple();
    }
}
Run Code Online (Sandbox Code Playgroud)

Apple会多久创建一次?我怀疑每次访问,是否正确?有关于此的文件吗?

java ejb java-ee cdi

6
推荐指数
2
解决办法
902
查看次数

@Initialized(ApplicationScoped.class) 事件何时在 CDI 中发送?

我试图在扩展中可观察到的 CDI 容器引发的事件的上下文中了解 @Initialized() 事件的生命周期/流程。

根据WELD 2 文档,容器生命周期事件是:

  • 发现Bean之前
  • ProcessAnnotatedType 和 ProcessSyntheticAnnotatedType
  • 类型发现后
  • ProcessInjectionTarget 和 ProcessProducer
  • 进程注入点
  • ProcessBean 属性
  • ProcessBean、ProcessManagedBean、ProcessSessionBean、ProcessProducerMethod 和 ProcessProducerField
  • 进程观察者方法
  • 豆子发现之后
  • 部署后验证
  • 关机前

我无法找到的是在此容器生命周期中将@Initialized触发事件的位置。我怀疑它是 AfterDeploymentValidation 完成的,但我找不到任何文档来支持这一事实。此外,我似乎无法在CDI 1.1 规范中找到任何指示何时/何处抛出 @Initalized 事件的内容。

例如,事件是在@PostConstruct发现的bean的所有方法执行之前还是之后抛出?该事件是在 EJB@Startup初始化之前还是之后引发的?是否有任何文档清楚地列出了 CDI 中这些事件的顺序/顺序?

java ejb cdi jakarta-ee

6
推荐指数
1
解决办法
2619
查看次数

带有 CDI 的 JSF 2.3 中的会话固定和会话作用域 Bean

在用户登录时更新 HTTP 会话是一种常见的最佳实践。这将强制使用新的会话 ID,避免会话固定漏洞。

当涉及@SessionScoped bean 时,是否有使用 CDI 实现此功能的首选模式?困难在于,通过使当前的 HTTP 会话无效,您将在下一个请求中获得一个不同的会话范围的 bean,但直到下一个请求才会如此。

例如,假设一个会话 bean 用于存储用户登录信息:

@Named("sessionbean")
@SessionScoped
public class SessionBean implements Serializable {
    private int userId;
    private String username;
    private List<String> privileges;

    // Accessors omitted 
}
Run Code Online (Sandbox Code Playgroud)

另一个用于管理登录的 bean:

@Named("loginbean")
@ViewScoped
public class LoginBean implements Serializable {

    private String username;
    private String password;
    @Inject private SessionBean session;
    @Inject private SessionManager sessionManager;
    @Inject private PrivilegeManager privilegeManager;      

    public String doLogin() {
        String destinationUrl;

        if (validate(username, password)) {
            FacesContext context = FacesContext.getCurrentInstance();

            // force …
Run Code Online (Sandbox Code Playgroud)

session jsf cdi jsf-2.3

6
推荐指数
1
解决办法
702
查看次数