Showing posts with label cdi. Show all posts
Showing posts with label cdi. Show all posts

Friday, May 10, 2019

CDI in IntelliJ Java Enterprise projects

I was following this https://www.jetbrains.com/help/idea/creating-and-running-your-first-java-ee-application.html tutorial to deploy a Primefaces application to Wildfly 16, but I kept getting an error


unable to find cdi beanmanager

I have tried adding Maven support and adding the dependency

<dependencies>

<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.2</version>
</dependency>

</dependencies>


to no avail.

Funnily, setting webapp version="2.3" instead of version="4.0" in web.xml fixes the problem.


Then I added CDI support as shown here:

https://www.jetbrains.com/help/idea/context-and-dependency-injection-cdi.html

and using version="4.0" and things are working.

Sunday, April 28, 2019

CDI and javax.transaction.TransactionScoped

I was wondering how TransactionScoped works, and I stumbled upon this wonderful example:

https://www.byteslounge.com/tutorials/java-ee-cdi-transactionscoped-example

This also is a great explanation on Injected beans https://www.byteslounge.com/tutorials/java-ee-cdi-dependency-injection-inject-tutorial

It's so clearly explained that I was deeply impressed by this www.byteslounge.com
Gonçalo Marques. We need more of this stuff. Often people post partial, overcomplicated examples.... Gonçalo instead goes straight to the point.

Thursday, August 2, 2018

CDI and WELD suck

A @Stateless bean could not be injected because not found by WELD

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type PersistenceService with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private com.pippo.pluto.paperino.rest.MafaldaController.persistenceService
  at com.pippo.pluto.paperino.rest.MafaldaController.persistenceService(MafaldaController.java:0)

 at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:362)
 at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:284)
 at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:137)
 at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:158)
 at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:501)
 at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:61)
 at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:59)
 at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:62)
 at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:55)
 at java.util.concurrent.FutureTask.run(FutureTask.java:266)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
 at java.lang.Thread.run(Thread.java:748)
 at org.jboss.threads.JBossThread.run(JBossThread.java:320)

https://docs.jboss.org/author/display/WFLY10/CDI+Reference

Even if the bean is a session bean, the archive (.jar) is not an “explicit bean archives (basically any archive containing the beans.xml file)“ because it doesn’t contain a beans.xml file (only the war file has a beans.xml file).

Since CDI 1.1 an archive can be implicit : “An implicit bean archive is any archive that contains one or more classes annotated with a bean defining annotation (scope annotation) or one or more session beans.”. Implicit archives don’t need a beans.xml.

But by default “implicit” is disabled! To enable it, you can either do the jboss-all.xml trick or do the “subsystem=weld:write-attribute(name=require-bean-descriptor,value=true)” trick. See again https://docs.jboss.org/author/display/WFLY10/CDI+Reference for more details. Or, you can simply add a beans.xml to the JAR.


If all this sounds to you like complete chaos and needless complication, it’s because it is!


Saturday, November 18, 2017

Injecting Logger

According to https://docs.jboss.org/weld/reference/2.4.0.CR1/en-US/html/injection.html :

import org.slf4j.Logger;

@Named
@SessionScoped
public class CaloriesController implements Serializable  {
 @Inject
 private Logger logger;
    public void insertUser() {
     logger.debug("insertUser");
    }
}


but this is not enough... you will get a "WELD-001408 Unsatisfied dependencies for type Logger with qualifiers @Default at injection point " ...

You have to prepare also a PRODUCER:

package org.pierre.calories.common;

import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.faces.bean.ManagedBean;
import javax.inject.Named;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Named
@ManagedBean
public class LoggingProducer {
 
 @Produces
 public Logger getLogger(final InjectionPoint ip) {
  return LoggerFactory.getLogger(ip.getMember().getDeclaringClass());
 }

}



See also https://stackoverflow.com/questions/19768405/weld-001408-unsatisfied-dependencies-for-type-logger-with-qualifiers-default


Again, one would hope that in 2017 these things were a bit better engineered and transparent.... but this is the world of IT, a huge morassic mess.... La Brea Tar Pits:



Tuesday, November 14, 2017

Public fields in CDI

in CDI one can't have a PUBLIC attribute in a RequestScoped variable:

@Named
@RequestScoped
public class EventViewBean implements Serializable {

    @Produces
    public List<Meal> meals;

    public void setMeals(List<Meal> meals) {
 this.meals = meals;
    }

    public List<Meal> getMeals() {
  return meals;
    }

}

otherwise you get this error:

WELD-000075 Normal scoped managed bean implementation class has a public field

To fix the issue, just remove the "public" in "public List<Meal> meals;" and don't ask questions... it's all too sad... just smile and say yes.

Sunday, November 5, 2017

CDI in Java SE 8

In Eclipse (pueah, I know, IntelliJ is much better) create a simple Java project, give it the Maven feature, and create this structure:


Add this dependency:

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


and the code to bootstrap the WELD engine is:

import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;

public class MyMain {
 public static void main(String[] args) {
  SeContainer container = SeContainerInitializer.newInstance().initialize();
  CDITester cdiTester = container.select(CDITester.class).get();
  cdiTester.greet();
 }
}



or also (thanks gist-it)



The beans.xml file is empty and required, without it you would get this error:


Exception in thread "main" java.lang.IllegalStateException: WELD-ENV-000016: Missing beans.xml file in META-INF
at org.jboss.weld.environment.se.Weld.initialize(Weld.java:742)
at org.jboss.weld.environment.se.Weld.initialize(Weld.java:174)
at org.pierre.cditests.MyMain.main(MyMain.java:8)




The whole solution is here https://github.com/vernetto/JavaMonAmour/tree/master/pvcdi.
When you start the MyMain inside Eclipse (no need to deploy it Wildfly!!!) you should see:


Nov 05, 2017 5:13:17 PM org.jboss.weld.bootstrap.WeldStartup
INFO: WELD-000900: 3.0.0 (Final)
Nov 05, 2017 5:13:17 PM org.jboss.weld.bootstrap.WeldStartup startContainer
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
Nov 05, 2017 5:13:17 PM org.jboss.weld.environment.se.WeldContainer fireContainerInitializedEvent
INFO: WELD-ENV-002003: Weld SE container aabfa8d7-3cf1-44da-8b63-173e651f18a8 initialized
Hello, pierre.
Weld SE container aabfa8d7-3cf1-44da-8b63-173e651f18a8 shut down by shutdown hook


I really wonder why Java still in 2017 doesn't offer you an ready-made CDI engine in SE.... in fact, I wonder why we still have this separation between SE and EE.... nonsense.... it will go away, like all the nonsense...


Incidentally , https://dzone.com/articles/how-to-inject-property-file-properties-with-cdi really simple way to inject property values with annotations (Spring has a similar concept




Tuesday, December 6, 2016

CDI context dependency injection

CDI is a powerful concept, but as usual implementation is pathetic (Spring, Java EE, whatever).
Annotations make code less readable, they leak concern, are extremely hard to debug (ever tried to find out why one of your references if not getting injected?). Read this excellent article https://www.javacodegeeks.com/2016/11/java-annotations-big-mistake.html
XML is easily broken, has to be mostly manually maintained, quickly becomes unmanageable and unstructured.
I still prefer a pure coded approach, where dependencies and injected by an "injector" bean, but in a Java EE container this would not retain the specific features of the bean. So it's not a choice available for now (maybe yes, I should investigate)

This is a quite decent introduction on CDI in a Java EE (CDI) container:









Saturday, October 31, 2015

Getting started with JSF and CDI and Primefaces

I have followed this tutorial http://reka-neva.blogspot.ch/2014/08/weblogic-jsf-2-tutorial.html


Deploy the application to a running WLS and test with http://localhost:7001/JSFWeb

You can login using this username/pw: ADMIN/password



The Java code uses the annotations
javax.enterprise.context.SessionScoped
javax.enterprise.inject.Model
javax.inject.Inject
javax.enterprise.inject.Produces


On the other hand, much more efficient if this approach https://www.mkyong.com/jsf2/primefaces/primefaces-hello-world-example/

and the code is https://github.com/vernetto/primefaces

Excellent article on JSF and CDI: https://dzone.com/articles/in-practice-dependency-injection-with-java-ee