有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java@EJB返回null

我是JBoss和J2EE的新手。我正在尝试用会话Bean联系单例Bean。长期来看,我想在Singleton bean中缓存一些信息,如果不可用,则在数据库中查找相关信息。但首先,我要创建最简单的用例

然而,当我在Eclipse中运行这个简单的用例(获取一个应用程序计数器)时,我得到了一个对EJB的空引用,我不确定下一步该转到哪里

我在运行Eclipse Keplar JDK1。7、JBoss AS 7.1、EJB 3.1

这是jsp文件

<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<jsp:useBean id="counter" class="com.bender.counter.Counter" scope="session"/>
<%-- <jsp:useBean id="counterBean" class="com.bender.counterbean.CounterBean" scope="application"/> --%>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Test Counter</title>
</head>

<body>
Hit Counter( <%=counter.getHitCount() %> )<br/>
<%-- Hit CounterBean( <%=counterBean.getHits() %> )<br/> --%>
</body>
</html>

这里是第一个会话bean

package com.bender.counter;

import com.bender.counterbean.CounterBean;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;

@SessionScoped
public class Counter {
    @EJB 
    CounterBean counterBean;

    private int hitCount;

    public Counter() {
        this.hitCount = 0;
    }

    public int getHitCount() {
        if (counterBean == null) {
            System.out.println("Failure");
            hitCount = -1;
        } else {
            hitCount = counterBean.getHits();
        }
        return hitCount;
    }

    public void setHitCount(int newHits) {
        this.hitCount = newHits;
    }
}

这是单身豆

package com.bender.counterbean;

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;

@Startup
@Singleton
public class CounterBean {
    private int hits = 1;

    public CounterBean() {
        super();
        System.out.println("In constructor of CounterBean.");
    }

    @PostConstruct
    public void init(){
        System.out.format("In post Construct of CounterBean, hits( %d )%n", this.hits);
    }

    // Increment and return the number of hits
    public int getHits() {
        return hits++;
    }
}

这是服务器的输出。日志请注意,counterbean似乎向jndi注册。还请注意,jsp中的注释已被删除。这是试图从jsp联系CounterBean。那次尝试是成功的,所以我认为CounterBean在服务器上成功运行

17:07:50,427 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-12) JBAS015876: Starting deployment of "Counter.war"
17:07:50,443 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-15) JNDI bindings for session bean named CounterBean in deployment unit deployment "Counter.war" are as follows:

    java:global/Counter/CounterBean!com.bender.counterbean.CounterBean
    java:app/Counter/CounterBean!com.bender.counterbean.CounterBean
    java:module/CounterBean!com.bender.counterbean.CounterBean
    java:global/Counter/CounterBean
    java:app/Counter/CounterBean
    java:module/CounterBean

17:07:50,458 INFO  [stdout] (MSC service thread 1-8) In constructor of CounterBean.

17:07:50,458 INFO  [stdout] (MSC service thread 1-8) In post Construct of CounterBean, hits( 1 )

17:07:50,474 INFO  [org.jboss.web] (MSC service thread 1-4) JBAS018210: Registering web context: /Counter
17:07:50,489 INFO  [org.jboss.as.server] (management-handler-threads - 83) JBAS018559: Deployed "Counter.war"
17:07:55,185 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Failure

谢谢你的帮助


共 (2) 个答案

  1. # 1 楼答案

    注入只在DI容器(在JBoss中是weld)知道对象的情况下起作用。这通常是因为容器本身创建了实例。还可以将现有对象传递给容器,让它注入所有依赖项

    CDI注入JSP页面似乎在JBoss AS 7中不起作用:

    也许你可以看看JSP的替代方案:

    如果你无法切换到其他技术,那么你可能不得不自己注射。使用以下方法让CDI容器对给定对象执行所有注入:

    public static <T> void programmaticInjection(Class<T> clazz, T injectionObject) throws NamingException {
        InitialContext initialContext = new InitialContext();
        Object lookup = initialContext.lookup("java:comp/BeanManager");
        BeanManager beanManager = (BeanManager) lookup;
        AnnotatedType<T> annotatedType = beanManager.createAnnotatedType(clazz);
        InjectionTarget<T> injectionTarget = beanManager.createInjectionTarget(annotatedType);
        CreationalContext<T> creationalContext = beanManager.createCreationalContext(null);
        injectionTarget.inject(injectionObject, creationalContext);
        creationalContext.release();
    }
    

    然后从JSP调用此方法:

    <h3>Inject Test</h3>
              <%
                        MyBean myBean = new MyBean();
                        myBean.programmaticInjection(MyBean.class, myBean);
                        // now call a method on myBean that invokes the injected EJB
              %>
    </body>
    </html>
    

    这里是一个简单的JSF bean,与您的类似:

    @Named("myBean")
    @SessionScoped
    public class MyBean implements Serializable {
        private static final Logger logger = LoggerFactory.getLogger(MyBean.class);
        private static final long serialVersionUID = 1L;
        private long taskId;
        @EJB
        private MyEjb myEjb;
    

    在调用programmaticInjection()之后,@EJB注释对象将被注入

  2. # 2 楼答案

    我可以通过添加JNDI查找来解决这个问题。我必须在JBoss AS 7.1实例中设置一些不正确的内容,这样一个bean就可以使用(默认)JNDI,而JSP页面可以(完全)访问JNDI。以下是更新(和清理)的代码

    JSP

    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <jsp:useBean id="counter" class="com.bender.counter.Counter" scope="session"/>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <title>Test Counter</title>
    </head>
    
    <body>
    Hit Counter( <%=counter.getHitCount() %> )<br/>
    </body>
    </html>
    

    会话Bean(注意@EJB被注释掉了) 包裹通讯。本德。柜台

    import com.bender.counterbean.CounterBean;
    
    import javax.ejb.EJB;
    import javax.enterprise.context.SessionScoped;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    @SessionScoped
    public class Counter {
    //    @EJB
        private CounterBean counterBean;
        {
            try {
                counterBean = (CounterBean) new InitialContext().lookup("java:global/Counter/CounterBean");
            } catch (NamingException e) { 
                e.printStackTrace();
            }
        }
    
        private int hitCount;
    
        public Counter() {
            this.hitCount = 0;
        }
    
        public int getHitCount() {
            if (counterBean == null) {
                System.out.println("Failure");
                hitCount = -1;
            } else {
                hitCount = counterBean.getHits();
            }
            return hitCount;
        }
    
        public void setHitCount(int newHits) {
            this.hitCount = newHits;
        }
    }
    

    还有独生子豆

    package com.bender.counterbean;
    
    import javax.annotation.PostConstruct;
    import javax.ejb.Singleton;
    import javax.ejb.Startup;
    
    
    @Startup
    @Singleton
    public class CounterBean {
        private int hits = 1;
    
        public CounterBean() {
            super();
            System.out.println("In constructor of CounterBean.");
        }
    
        @PostConstruct
        public void init(){
            System.out.format("In post Construct of CounterBean, hits( %d )%n", this.hits);
        }
    
        // Increment and return the number of hits
        public int getHits() {
            return hits++;
        }
    }
    

    这是JBoss控制台的输出

    16:21:55,740 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-12) JBAS015876: Starting deployment of "Counter.war"
    16:21:55,888 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named CounterBean in deployment unit deployment "Counter.war" are as follows:
    
        java:global/Counter/CounterBean!com.bender.counterbean.CounterBean
        java:app/Counter/CounterBean!com.bender.counterbean.CounterBean
        java:module/CounterBean!com.bender.counterbean.CounterBean
        java:global/Counter/CounterBean
        java:app/Counter/CounterBean
        java:module/CounterBean
    
    16:21:56,033 INFO  [stdout] (MSC service thread 1-7) In constructor of CounterBean.
    
    16:21:56,033 INFO  [stdout] (MSC service thread 1-7) In post Construct of CounterBean, hits( 1 )
    
    16:21:56,088 INFO  [org.jboss.web] (MSC service thread 1-15) JBAS018210: Registering web context: /Counter
    16:21:56,093 INFO  [org.jboss.as] (MSC service thread 1-15) JBAS015874: JBoss AS 7.1.0.Final "Thunder" started in 2001ms - Started 185 of 258 services (72 services are passive or on-demand)
    16:21:56,176 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "Counter.war"
    16:22:11,455 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) In constructor of CounterBean.