【问题标题】:Weld not initializing properly焊接未正确初始化
【发布时间】:2014-09-02 12:13:15
【问题描述】:

我正在搭建JavaEE7中学习CDI的基本环境。我有以下代码用于启动Weld。只是启动和关闭。

package com.anshbansal;

import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;

public class Main {
    public static void main(String[] args) {
        Weld weld = new Weld();
        WeldContainer container = weld.initialize();
        weld.shutdown();
    }
}

我在我的控制台上得到关注。

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/Softs/Programming/Java/Java%20JARs/JBoss%20Weld-2.0.3/jar/weld-se.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/Softs/Programming/Java/Java%20JARs/JBoss%20Weld-2.0.3/jar/weld-servlet.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory]
[main] INFO org.jboss.weld.Version - WELD-000900 2.0.3 (Final)
[main] INFO org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

有问题的行是WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.。这仅仅意味着依赖注入将不起作用。但我不确定是什么问题。我在CLASSPATH 中添加了weld-se.jar。我什至还没有达到初始化对象的地步,那么为什么会出现这个问题?

Weld 的官方文档也给出了我在阅读 this answer 后得到的相同代码。 “Antonio Goncalves”的“Beginning Java EE 7”一书中使用了相同的代码。我已经验证了来自this github location 的导入。因此,如果我使用了正确的类路径并且没有创建任何对象,那么为什么会出现这个问题?

【问题讨论】:

  • 你不会通过使用 Java SE Weld 包来学习 Java EE。
  • @SotiriosDelimanolis 我...我只是不知道我是如何错过它是 se 而不是 ee。我复制并粘贴了最初运行它的代码。

标签: java jakarta-ee cdi weld


【解决方案1】:

即使您错过将 beans.xml 文件保存在 test/resource/META-INF 文件夹中,也会出现此问题。\

确保您将 beans.xml 文件作为 上下文和依赖注入的强制文件。

【讨论】:

    【解决方案2】:

    要设置学习 CDI 环境,您只需要一个 CDI 实现,例如 Weld 参考实现;您不需要 Java EE 容器。

    简单的方法是在pom.xml 中创建一个依赖项的maven 项目: (确保在运行java应用程序之前在META-INF目录中创建一个空的或最小的beans.xml文件。如果你使用maven,你可以在src/main/resources目录中创建META-INF)

    <dependency>
        <groupId>org.jboss.weld.se</groupId>
        <artifactId>weld-se</artifactId>
        <version>2.3.4.Final</version>
    </dependency>
    

    这是应用程序:

    public class CdiApplication {
        private Weld weld;
        private WeldContainer container;
        private BookService bookService;
    
        private void init() {
            weld = new Weld();
            container = weld.initialize();
            BookService = container.instance().select(BookService.class).get();
        }
    
        private void start() {
            Book book = bookService.createBook("My title", "My description", 23.95);
            System.out.println(book);
        }
    
        private void shutdown() {
            weld.shutdown();
        }
    
        public static void main(String[] args) {
            CdiApplication application = new CdiApplication();
            application.init();
            application.start();
            application.shutdown();
        }
    
    }
    

    Book 类:

    public class Book {   // Book is a POJO
        private String title;
        private String description;
        private double price;
        private String id;    // ISBN or ISSN
        private Date instanciationDate;
    
        public Book() {   // default constructor
    
        }
    
        public Book(String title, String description, double price) {
            this.title = title;
            this.description = description;
            this.price = price;
            // the BookService is responsible to set the id (ISBN) and date fields.
        }
    
        // setters and getters
        // toString method
    }
    

    还有BookService 类使用注入的NumberGenerator 创建一本书并设置其实例化日期和ID (ISBN):

    public class BookService {
        @Inject
        private NumberGenerator numberGenerator;
    
        private Date instanciationDate;
    
        @PostConstruct
        private void setInstanciationDate() {
            instanciationDate = new Date();
        }
    
        public Book createBook(String title,
            String description, double price) {
    
            Book book = new Book(title, description, price);
            book.setId(numberGenerator.generateNumber());
            book.setDate(instanciationDate);
    
            return book;
        }
    
    }
    

    在 servlet 环境中,servlet 容器将负责引导 CDI,这意味着您必须在 Java EE 容器(例如 Tomcat 或 Wildfly)上部署“Web 应用程序”。

    【讨论】:

      【解决方案3】:

      运行 Java EE 应用程序需要应用程序服务器(或容器)。在集成运行企业应用程序所需的不同服务(安全性、消息传递、事务等)方面,此容器让您的生活变得非常简单。

      如果您不使用应用程序服务器(就像您在示例中所做的那样),您必须自己进行此集成(即构建您自己的服务器)。既然存在服务器,这是一项非常艰巨且无用的任务。

      您在问题中显示的代码是,当您不想要或可以使用容器时,如何使用 Weld 的专有部分手动启动 CDI 容器。

      如果您仔细阅读 Antonio 的书,您会在 第 xxxiv 页 部分中的 “下载和运行代码” 部分中声明您需要部署您的Glassfish 4 上的代码,其中一个开源 Java EE 7 服务器(另一个是 JBoss Wildfly)

      本书的

      附录 A(第 539 页)以非常精确的方式描述了如何设置环境以运行书籍示例和简单的 Java EE 应用程序。请按照本部分的说明进行操作,您会发现开发和部署 Java EE 7 应用程序非常简单。

      【讨论】:

      • 我已经在使用应用程序服务器,即 weblogic 12c,并且已经使用 EJB 3 应用程序和 Servlet/JSP 作为前端测试了部署。我还部署了第 2 章中给出的应用程序,但是带有main 的客户端无法正常工作。我已经尝试过他使用 apache-maven-3.2.3 的方法。但是正如我在赏金描述中提到的那样,确实会发生未初始化的错误。部署在这里不是问题。运行客户端是问题所在。即使使用Maven也会出现错误。
      • 好的,我得到了这个例子。我运行了本书 github repo (github.com/agoncal/agoncal-book-javaee7) 中的代码。事务警告是正常的,因为您没有事务管理器。但这是一个警告,而不是错误。代码仍在执行。 Weld 仅警告您交易将受到限制。代码正在运行。
      • @SotiriosDelimanolis 对这个问题的评论可能是正确的解释。
      • 如果这是一个 CDI 问题,我会同意你的看法。但实际上这是一个 JAVA EE 7 书籍问题。不知道为什么作者在里面放了一个带有weld-se的例子。
      • 是的例子是有效的,但不是所有的部分。我看不到方法调用周围的 LoggingInterceptor 消息。所以我想,焊接初始化在某些时候失败了,并且某些功能被禁用了。
      【解决方案4】:

      您的设置适合​​在 Java SE 中学习 CDI。

      为了在 Java EE 中使用 CDI,您显然需要一个 Java EE 容器,一个带有 main 方法的普通旧应用程序是不行的。

      Weld 只是告诉您事务不可用(因为您没有在 EE 容器中运行),因此任何与事务相关的 CDI 功能都将被禁用。

      依赖注入适用于您的情况,只要您不尝试注入任何 Java EE 对象或使用任何需要 Java EE 容器的 CDI 功能。

      【讨论】:

      • 所以我必须使用应用服务器?
      • 仅当您想使用 Java EE 功能时。
      • 我认为我们需要更好地了解您想要做什么。如前所述,这只是一个警告,即事务支持不可用。如果您要做的是让事情在 servlet 容器中工作,您可以在 Tomcat 中使用 Weld Servlet。如果你只是想编写一个基本的 Java SE 程序,这会很好。
      • 我正在搭建JavaEE7学习CDI的基础环境。我也不知道 CDI 是 Java SE 的一部分。我只在 Java EE 中看到过 CDI。那么我将如何使用应用服务器运行main?我已经安装了 Glassfish。
      • @JohnAment 我在写上面的评论时忘记添加名字了。
      猜你喜欢
      • 2011-06-08
      • 1970-01-01
      • 2020-04-21
      • 2012-06-17
      • 2022-01-22
      • 2014-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多