我是JBoss和J2EE的新手。我正在尝试使用Session bean联系Singleton 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;
}
}
这是Singleton Bean
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++;
}
}
这是server.log的输出。请注意,反bean似乎注册了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
感谢您的帮助!
答案 0 :(得分:1)
注射仅在DI容器(在JBoss中焊接)知道对象时才起作用。这通常是因为容器本身创建了实例。您也可以将现有对象传递给容器,让它注入所有依赖项。
看起来在JSP页面中注入CDI在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>
MyBean
这里是一个简单的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注释对象。
答案 1 :(得分:0)
我能够通过添加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被注释掉了) 包com.bender.counter;
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;
}
}
和Singleton Bean
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.