CDI装饰者可以成为无国籍的ejb吗?
我试过了:
@Decorator
@Stateless
public class WarehouseHandlingDecorator implements SerialKitServiceWarehouseHandling {
@Inject
@Any
@Delegate
protected SerialKitServiceWarehouseHandling serialKitServiceWarehouseHandling;
...
}
Run Code Online (Sandbox Code Playgroud)
我部署在JBoss 6.1上,我收到以下消息:
WELD-000038不能将@Delegate放在一个不在Decorator上的注入点:@New Session bean [类com.eggsweb.production.services.WarehouseHandlingDecorator with qualifiers [@New]; 本地接口是[SerialKitServiceWarehouseHandling]
我试图在类级别学习带有bean验证的JSF 2.0,如下所示: -
实用程序
@Singleton
public class MyUtility {
public boolean isValid(final String input) {
return (input != null) || (!input.trim().equals(""));
}
}
Run Code Online (Sandbox Code Playgroud)
约束注释
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.TYPE,
ElementType.ANNOTATION_TYPE,
ElementType.FIELD
})
@Constraint(validatedBy = Validator.class)
@Documented
public @interface Validatable {
String message() default "Validation is failure";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Run Code Online (Sandbox Code Playgroud)
约束验证器
public class Validator extends ConstraintValidator<Validatable, MyBean> {
//
//----> Try to inject the utility, but it cannot as null.
//
@Inject
private MyUtility myUtil; …Run Code Online (Sandbox Code Playgroud) 我在IntelliJ中有一个maven项目,我试图将war文件部署到jetty容器中.这样做的目的是对所述war文件中的一些功能进行快速集成测试.
由于开箱即用Jetty没有附带CDI或JNDI,我试图添加对这些的支持,但遇到了一些问题.例如,我在启动时收到以下错误:
15:30:50 [34mINFO [0;39m o.a.s.c.CdiObjectFactory - [lookup]: Checking for BeanManager under JNDI key java:comp/BeanManager
15:30:50 [39mDEBUG[0;39m o.a.s.c.CdiObjectFactory - [lookup]: BeanManager lookup failed for JNDI key java:comp/BeanManager
Run Code Online (Sandbox Code Playgroud)
我已将焊接servlet jar包含在我的pom中,并且还将焊接侦听器添加到web.xml中,但它仍然无效.我正在使用Jetty 9.有什么想法吗?
的pom.xml
Run Code Online (Sandbox Code Playgroud)<dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-core</artifactId> <version>2.0.4.Final</version> </dependency>web.xml中
Run Code Online (Sandbox Code Playgroud)<listener> <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class> </listener>
<resource-env-ref>
<description>Object factory for the CDI Bean Manager</description>
<resource-env-ref-name>BeanManager</resource-env-ref-name>
<resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
</resource-env-ref>
Run Code Online (Sandbox Code Playgroud) 任何人都可以向我解释为什么第一个和第二个案例失败导致NullPointerException因为b2和/或b3在构造函数中仍然为空Bean1,当第三种情况正常时.
在所有情况下都有:
@Stateless
public class Bean2 {
@Inject
private Bean3 b3;
public Bean2(){
}
}
Run Code Online (Sandbox Code Playgroud)
第一种情况:(失败)
@Singleton
@StartUp
public class Bean1 {
@Inject
private Bean2 b2;
public Bean1(){
b2.someMethod(); // b2 throws null pointer exception
}
}
Run Code Online (Sandbox Code Playgroud)
第二种情况:(失败)
@Singleton
@StartUp
public class Bean1 {
private Bean2 b2;
public Bean1(){
b2 = new Bean2();
b2.someMethod(); // b3 throws null pointer exception
}
}
Run Code Online (Sandbox Code Playgroud)
第三种情况:(成功)
@Singleton
@StartUp
public class Bean1 { …Run Code Online (Sandbox Code Playgroud) 我发现在servlet donot中创建的新线程包含servlet/CDI上下文.我创建了一个HelloWorld servlet(如下所示)来试验这个问题.在下面的示例中,您将看到我在新的Thread(FutureTask)中运行'doIt()'函数.但是它返回NULL但是当我直接调用'doIt()'方法时,BeanManager不是NULL.
/**
* Servlet implementation class HelloWorld
*/
@WebServlet("/HelloWorld")
public class HelloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(HelloWorld.class
.getName());
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<head><title>Hello World Servlet</title></head>");
writer.println("<body>");
writer.println("<h1>Context injection into Thread Experiment</h1>");
try {
// 1. This is NOT working
new Thread(testTask).start();
testTask.get(5000, TimeUnit.SECONDS);
// 2. This is working …Run Code Online (Sandbox Code Playgroud) 在CDI中,我能够注入一个具有特定范围的bean,即定义bean类的范围.但是如果我创建没有任何作用域的bean类,并且在注入点为bean提供范围,该怎么办呢?我的要求是在后一种情况下使注入时间范围成为可能.问题是注入正在发生dependent scope而不是所需的注释范围,除非我使用a producer.
例如:
情况1:
当我在类声明中声明bean的范围时,如下所示:
@ApplicationScoped
class UserDetails {
...
}
Run Code Online (Sandbox Code Playgroud)
并注入如下:
@ViewScoped
class UserView {
@Inject
UserDetails userDetails;
.
.
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作.在应用程序范围中注入的bean在整个应用程序中可用于所有其他bean.
案例2:
但是当我在课堂声明中没有给出范围时:
class UserDetails {
...
}
Run Code Online (Sandbox Code Playgroud)
并注入这样(在注射点给出范围):
@ViewScoped
class UserView {
@Inject @ApplicationScoped
UserDetails userDetails;
.
.
}
Run Code Online (Sandbox Code Playgroud)
这失败了!注入的bean没有注入application scope但dependent scope反过来(View Scope在我的情况下).
我必须创建一个Producer&a Qualifierwhere @Produces方法提供所需的bean application scope.我觉得如果我必须在这种情况下注入bean类UserDetails,那么这个生成器/限定符扩展会成为开销application scope.
事实上,UserDetails类是第三方jar的一部分.此类没有声明任何范围,并且是POJO.我无法更改其源代码.
基于以上讨论,我有两个问题:
为什么有人会在知道要在特定范围内注入bean时创建没有范围定义的bean类?这种做法在设计方面有用吗?
由于我无法控制bean类的源代码,并且因为它们与任何范围都没有关联,所以生产者/限定符扩展是在所需范围内注入此类bean的唯一好方法吗?
我试图在我通过Docker安装的Websphere Liberty配置文件中运行的非常简单的Web应用程序中使用CDI.
但是注入失败,除非我@ApplicationScoped在注入的bean上指定范围注释(例如),尽管根据许多在线教程(例如,这个),Java EE规范不要求这样做.
以下是失败的代码:
HelloWorldServlet.java
package my.simple.app;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {
static String PAGE_HEADER = "<html><head /><body>";
static String PAGE_FOOTER = "</body></html>";
@Inject
HelloService helloService;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println(PAGE_HEADER);
writer.println("<h1>" + helloService.createHelloMessage("World") + "</h1>");
writer.println(PAGE_FOOTER);
writer.close();
}
}
Run Code Online (Sandbox Code Playgroud)
HelloService.java
package my.simple.app;
public class HelloService { …Run Code Online (Sandbox Code Playgroud) 我已经在网站上查看了与该错误有关的其他问题,但其中大多数都是关于SessionScope的,或者没有答案。唯一可能有用的是从线程中调用bean时,作用域类型javax.enterprise.context.RequestScoped没有活动上下文,但它不在我所拥有的上下文中。
我在Wildfly 10.1(Java ee 7)上运行JAX-RS端点。看起来像这样:
@Path("")
public class ServerResource {
@Inject
Order order;
@Resource
ManagedExecutorService mes;
@PUT
@Path("/prepareOrder")
public void prepareOrder(@Suspended AsyncResponse response) {
mes.execute(() -> {
try {
Item item = new Item(); // JPA entity
order.setItem(item); // line 71
// call a service to save the order data (like item) to the DB
} catch (Exception e) {
e.printStackTrace();
response.resume(false);
}
response.resume(true);
});
}
}
Run Code Online (Sandbox Code Playgroud)
我添加try-catch仅仅是因为这个问题,它通常不存在。 Order是
@Stateful
@RequestScoped
public class Order {
private Item …Run Code Online (Sandbox Code Playgroud) 我正在测试一些关于Paraya 5的JMS工作.具体来说是5.181.下面是我简单的无状态bean的代码. @JMSConnectionFactory失败!该JMSContext context变量始终null.然而@Resource(lookup = "jms/HelloWorldConnectionFactory")成功......任何想法为什么?我更喜欢使用JMSContext.
@Stateless
public class HelloWorldMessageSender {
@JMSConnectionFactory("jms/HelloWorldConnectionFactory")
protected JMSContext context;
@Resource(lookup = "jms/HelloWorldConnectionFactory")
protected ConnectionFactory connectionFactory;
@Resource(lookup = "jms/HelloWorldQueue")
protected Queue queue;
public String send() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS");
String txt = String.format("Hello world message %s", sdf.format(new Date()));
if (context != null) {
System.out.printf("Use JMSContext to produce%n");
context.createProducer().send(queue, txt);
}
if (connectionFactory != null) {
System.out.printf("Use ConnectionFactory to produce%n");
try (
Connection connection …Run Code Online (Sandbox Code Playgroud) 当文档(行)插入MongoDB集合时,尝试让EJB通知我的XHTML JSF页面.
由于我之前的问题的答案得到了JSF 2.3的工作:
然而,在将服务器端代码添加到我的EJB并尝试将我的EAR部署到WildFly 12.0.0.Final之后,我得到了一个用于PushContext的java.lang.ClassNotFoundException:
Caused by: java.lang.RuntimeException: WFLYSRV0177: Error getting reflective information for class com.notifywell.ejb.FoodsCosmeticsMedicinesEJB with ClassLoader ModuleClassLoader for Module "deployment.NOTiFYwell.ear.NOTiFYwellJAR.jar" from Service Module Loader
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
at java.lang.Class.getDeclaredFields(Class.java:1916)
at org.jboss.as.server.deployment.reflect.ClassReflectionIndex.<init>(ClassReflectionIndex.java:72)
at org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex.getClassIndex(DeploymentReflectionIndex.java:70)
... 13 more
Caused by: java.lang.ClassNotFoundException: javax.faces.push.PushContext from [Module "deployment.NOTiFYwell.ear.NOTiFYwellJAR.jar" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:199)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:412)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:400)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116)
... 18 more
Run Code Online (Sandbox Code Playgroud)
在EJB中使用:
@Inject
@Push
private PushContext push;
Run Code Online (Sandbox Code Playgroud)
包含在:
jboss-jsf-api_2.3_spec-2.3.3.SP1.jar
Run Code Online (Sandbox Code Playgroud)
当我添加@Inject到@Push.时会发生这种情况.
WildFly 12和/或JSF …