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?
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With