Weld not initializing properly

10,918

Solution 1

Running Java EE application requires an Application server (or container). This container makes your life far simple regarding the integration of different services (security, messaging, transaction, etc...) needed to run an enterprise application.

If you don't use an application server (like you are doing in your example) you have to make this integration yourself (i.e build your own server). That's a very hard and useless task since servers exist.

The code you show in your question is how you can use the proprietary part of Weld to start a CDI container by hand when you don't want or can use a container.

If you read carefully Antonio's book, you'll see that on page xxxiv in section 'Download and Running the Code' it is stated that you need to deploy your code on Glassfish 4, one of the open source Java EE 7 server (the other being JBoss Wildfly)

Appendix A of the book (page 539) describe in a very precise way how to set up your environment to run book examples and simple Java EE applications. Please follow instruction in this part and you'll see that developing and deploying Java EE 7 application si very simple.

Solution 2

Your setup is ok for learning CDI in Java SE.

For using CDI in Java EE, you obviously need a Java EE Container, a plain old application with a main method won't do.

Weld is simply telling you that transactions are not available (since you're not running in an EE container), so any transaction-related CDI features will be disabled.

Dependency injection will work in your case, as long as you don't try to inject any Java EE objects or use any CDI features that require a Java EE container.

Solution 3

To set up a learning CDI environment, all you need is a CDI implementation such as the Weld reference implementation; you don't need a Java EE container.

The easy way is to create a maven project with a dependency in pom.xml: (Make sure to create an empty or the minimal beans.xml file in META-INF directory before you run the java application. If you go for maven, you can create META-INF in the src/main/resources directory)

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

Here's the application:

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();
    }

}

The Book class:

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
}

And the BookService class to create an book and set its instanciation date and id (ISBN) using the injected NumberGenerator:

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;
    }

}

In a servlet environment, the servlet container will responsible to bootstrap the CDI, meaning that you have to deploy your "web application" on a Java EE container such as Tomcat or Wildfly.

Share:
10,918
Aseem Bansal
Author by

Aseem Bansal

My Blog, My LinkedIn

Updated on June 12, 2022

Comments

  • Aseem Bansal
    Aseem Bansal almost 2 years

    I am setting up basic environment for learning CDI in JavaEE7. I have the following code for starting Weld. Just a startup and shutdown.

    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();
        }
    }
    

    I am getting following on my console.

    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.
    

    The problematic line is WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.. This simply means that Dependency injection will not work. But I am not sure what is the problem. I have added weld-se.jar in my CLASSPATH. I have not even reached the point of initializing an object then why is this problem occurring?

    Weld's official documentation also gives same code which I got after reading this answer. The same code is used in the book "Beginning Java EE 7" by "Antonio Goncalves". I have verified the imports from this github location. So if I have used correct class path and have not created any object then why is this problem occurring?

  • Aseem Bansal
    Aseem Bansal almost 10 years
    So I will have to use an application server?
  • Harald Wellmann
    Harald Wellmann almost 10 years
    Only if you want to use Java EE features.
  • John Ament
    John Ament almost 10 years
    I think we need to understand a little better what you're trying to do. As mentioned, this is simply a warning that Transaction support isn't available. IF what you're trying to do is make things work in a servlet container, you can use Weld Servlet in Tomcat. If you're trying to just write a basic Java SE program, this will do fine.
  • Aseem Bansal
    Aseem Bansal almost 10 years
    I am setting up basic environment for learning CDI in JavaEE7. Also I am not aware that CDI was part of Java SE. I have only seen CDI in Java EE. So how will I run the main using an application server? I have already installed Glassfish.
  • Aseem Bansal
    Aseem Bansal almost 10 years
    @JohnAment I forgot to add the name when writing above comment.
  • Aseem Bansal
    Aseem Bansal over 9 years
    I am using an application server already i.e. weblogic 12c and have tested deployment using EJB 3 application with Servlet/JSP as front-end. I have also deployed the application deployed the one given in Chapter 2 but the client with main is not working. I have tried his method of using apache-maven-3.2.3. But the error of not initializing does occur as I have mentioned in the bounty description. Deployment is not a issue here. Running the client is the issue. The error occurs even when Maven is used.
  • Antoine Sabot-Durand
    Antoine Sabot-Durand over 9 years
    Ok I got the example. I ran the code from the book github repo (github.com/agoncal/agoncal-book-javaee7). The transactional warning is normal since you don't have a transaction manager. But it's a warning, not a error. The code is still executed. Weld only warns you that transactions will be limited. The code is working.
  • Aseem Bansal
    Aseem Bansal over 9 years
    The comment on the question by @SotiriosDelimanolis might be the right explanation.
  • Antoine Sabot-Durand
    Antoine Sabot-Durand over 9 years
    If it was a CDI question I would agree with you. But in fact it's a JAVA EE 7 book question. I don't know why the author put an example with weld-se in it.
  • yuriy.weiss
    yuriy.weiss almost 9 years
    Yes example is working, but not all parts. I cannot see LoggingInterceptor messages around method invocations. So I suppose, that weld initialization failed at some point, and some functionality is disabled.