EJB 项目抛出 WELD-001408 异常:不满足的依赖关系

EJB project throws WELD-001408 Exception: Unsatisfied dependencies

我用 Eclipse 创建了一个 EJB 项目 IDE。我的应用服务器是 Glassfish 4。我使用的数据库是 Oracle。现在当我 运行 代码时,我收到错误消息:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Set<Service> with qualifiers @Default at injection point

看看我下面的代码。

客户:

package de.java2enterprise.onlineshop.ejb;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Customer implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    private String email;
    private String password;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

RegisterBean:

package de.java2enterprise.onlineshop.ejb;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class RegisterBean implements RegisterBeanRemote, RegisterBeanLocal {

    @PersistenceContext
    private EntityManager em;

    public RegisterBean() {
    }

    @Override
    public String persist(String email, String password) {
        Customer customer = new Customer();
        customer.setEmail(email);
        customer.setPassword(password);
        em.persist(customer);
        return email + " persisted";
    }
}

RegisterBeanLocal:

package de.java2enterprise.onlineshop.ejb;

import javax.ejb.Local;

@Local
public interface RegisterBeanLocal {
    public abstract String persist(
            String email,
            String password);
}

RegisterBeanRemote:

package de.java2enterprise.onlineshop.ejb;

import javax.ejb.Remote;

@Remote
public interface RegisterBeanRemote {
    public abstract String persist(
            String email,
            String password);
}

最后一个是我的 RegisterController,它注入了 RegisterBeanLocal cass:

package de.onlineshop_web.bean;

import java.io.Serializable;

import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;

import de.java2enterprise.onlineshop.ejb.RegisterBeanLocal;

@Named
@RequestScoped
public class RegisterController implements Serializable {

    private static final long serialVersionUID = 1L;

    private String email;
    private String password;

    @EJB
    private RegisterBeanLocal registerBeanLocal;

    public String persist() {
        String msg = registerBeanLocal.persist(email, password);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(msg));
        return "register";
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

您的代码中不太可能实际定义了 Set<Service>,或者至少这是我要处理的假设。

此错误不明确。但是,如果您可以提供您收到的异常的完整详细信息,而不是停留在 qualifiers @Default at injection point,这将有助于获得更清晰的解决方案。

我的预感:

您提到了一个 EJB 项目,但是您在应用程序中定义了对 JSF 代码 (javax.faces) 的依赖项。 Glassfish 不会在直接部署的 EJB 上激活 JSF。

现在,您可能提到了 EJB 项目,但实际上您部署的是 WAR。如果是这样,我会检查 WAR 是否打包了不必要的依赖项。

我相信您正在项目中使用 Google Guava,正如@maress 在他的评论中暗示的那样。有 3 种可能的解决方案:

  • 将 Guava 降级到版本 13,据报道没有这个问题
  • 在 Guava 的 JAR 文件中的 META-INF 目录中添加 this beans.xml 文件
  • 将 Weld 升级到版本 2.2(或将整个 Glassfish 升级到 4.1),它实现了 CDI 1.2 的维护版本,修复了 Guava 的问题

背景:

Set<Services> 来自 Guava。 Guava 使用 @Inject 注释,而且在这种特定情况下它还使用注释 @Singleton。在 CDI 1.1 (Java EE 7) 中,用 @Singleton 注释的 bean 被自动视为 CDI bean,当 CDI 计算这个 Guava class 的依赖项时,它失败了——更多细节在这里:code.google.com/p/guava-libraries/issues/detail?id=1433

添加到 guava jar 文件 beans.xml 中,用 bean-discovery=none 禁用 CDI 解决了问题,但仅适用于 Java EE 7(另一方面,它使旧的 CDI 机制出现问题用于 Java EE 6)。最后,CDI 规范 1.2 从注释中删除了注释 @Singleton,这将 classes 变成了 CDI bean,这也解决了任何版本的 Guava 的问题。