Select Menu JSF to CDI differences - jsf-2

I want to use the arquillian warp test framework for a JSF project I am developing. I understand that I need to use the CDI annotations instead of the JSF ones to get this to work. I am using #ViewScoped beans so I have included seam-faces in my project to deal with this (i am running on JBoss 7). I have modified my beans to use #Named and where I was using #PostConstruct I have put this into the constructor which all seems to be okay.
When I access a view with a selectOneMenu it never has any list items. Here is the code form the view and the bean.
View:
<h:selectOneMenu value="#{ngoBean.ngo.country}" >
<f:selectItems value="#{ngoBean.countryValues}" />
</h:selectOneMenu>
Bean:
import com.a.Facade;
import com.a.CountryEnum;
import com.a.GoverningBody;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Created with IntelliJ IDEA.
*/
#Named("ngoBean")
#ViewScoped
public class NgoBean implements Serializable {
private GoverningBody ngo = new GoverningBody();
private List<GoverningBody> ngoList;
private boolean edit;
private List<SelectItem> countryValues;
#EJB(beanName = "NgoFacadeImpl")
private Facade<GoverningBody> ngoController;
public NgoBean(){
}
#PostConstruct
public void init(){
//TODO this is a bad way of loading db data i should change it
ngoList = ngoController.findAll();
countryValues = initCountryValues();
}
public void add(){
ngoList.add(ngoController.save(ngo));
//reset the variable
ngo = new GoverningBody();
}
public void edit(GoverningBody item) {
this.ngo = item;
edit = true;
}
public void save() {
ngo = ngoController.update(ngo);
edit = false;
}
public void delete(GoverningBody item) {
ngoController.delete(item);
ngoList.remove(item);
}
public List<GoverningBody> getNgoList() {
return ngoList;
}
public GoverningBody getNgo() {
return ngo;
}
public boolean isEdit() {
return edit;
}
public List<SelectItem> getCountryValues() {
return countryValues;
}
public void setCountryValues(List<SelectItem> countryValues) {
this.countryValues = countryValues;
}
public List<SelectItem> initCountryValues() {
List<SelectItem> items = new ArrayList<>(CountryEnum.values().length);
int i = 0;
for(CountryEnum g: CountryEnum.values()) {
items.add(new SelectItem(g, g.getName()));
}
System.out.println("items = " + items);
return items;
}
}
I tried annotating the method with #Factory("countryValues") but this didn't seem to help.

This problem was unrelated to the symptom. The root cause of the problem was an incorrectly located beans.xml this should have be in the WEB-INF directory of the war not the META-INF directory of the ear.
I also changed the seam-faces dependency to use apache CODI, this is not necessary but this uses #ViewAccessScoped instead of #ViewScoped the different name is less ambiguous I think.

Related

Whitelisting application properties in Spring Cloud Data Flow

When I create a custom app for SCDF I can, according to the reference define relevant properties that are visible through the dashboard when creating a new stream/task. I created a spring-configuration-metadata-whitelist.properties file like this:
configuration-properties.classes=com.example.MySourceProperties
configuration-properties.names=my.prop1,my.prop2
When I create a new stream definition through the dashboard all properties defined in com.example.MySourceProperties are displayed in the properties dialog, but my.prop1 and my.prop2 are not. Both properties aren't optional and must always be set by the user. How can I include them in the properties dialog?
This tells it which class to pull these properties from Task1 properties class
That we can use with "#EnableConfigurationProperties(Task1Properties.class) declaration
configuration-properties.classes=com.shifthunter.tasks.Task1Properties
Task1Properties.java
package com.shifthunter.tasks;
import org.springframework.boot.context.properties.ConfigurationProperties;
#ConfigurationProperties("pulldata-task")
public class Task1Properties {
/**
* The path to get the source doc from
*/
private String sourceFilePath;
/**
* The path to put the destination doc
*/
private String destinationFilePath;
/**
* Property to drive the exit code
*/
private String controlMessage;
public String getSourceFilePath() {
return sourceFilePath;
}
public void setSourceFilePath(String sourceFilePath) {
this.sourceFilePath = sourceFilePath;
}
public String getDestinationFilePath() {
return destinationFilePath;
}
public void setDestinationFilePath(String destinationFilePath) {
this.destinationFilePath = destinationFilePath;
}
public String getControlMessage() {
return controlMessage;
}
public void setControlMessage(String controlMessage) {
this.controlMessage = controlMessage;
}
}
ShiftHunterTaskPullDataApp.java
package com.shifthunter.tasks;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#EnableTask
#EnableConfigurationProperties(Task1Properties.class)
#SpringBootApplication
public class ShiftHunterTaskPullDataApp {
public static void main(String[] args) {
SpringApplication.run(ShiftHunterTaskPullDataApp.class, args);
}
#Bean
public Task1 task1() {
return new Task1();
}
public class Task1 implements CommandLineRunner {
#Autowired
private Task1Properties config;
#Override
public void run(String... strings) throws Exception {
System.out.println("source: " + config.getSourceFilePath());
System.out.println("destination: " + config.getDestinationFilePath());
System.out.println("control message: " + config.getControlMessage());
if(config.getControlMessage().equals("fail")) {
System.out.println("throwing an exception ...");
throw new Exception("I'm ANGRY");
}
System.out.println("pulldata-task complete!");
}
}
}
Sream Dataflow task-pull-data
app register --name task-pull-data --type task --uri maven://com.shifthunter.tasks:shifthunter-task-pulldata:jar:0.0.1-SNAPSHOT
task-pull-data - Details

How can I use dependency injection in a Gluon Desktop app?

Does anyone know if there is any easy way to use dependency injection within the FXML controllers of a Gluon Desktop (ParticleApplication) app? There is already #Inject used for things like
public class HomeController {
#Inject ParticleApplication app;
#Inject private ViewManager viewManager;
#Inject private StateManager stateManager;
(as part of the framework) but I would like to be able to #Inject my own objects.
EDIT: An answer suggested to use Gluon Ignite, but I'm still having trouble figuring it out. Here is some of my attempted code:
My ParticleApplication class:
package com.gluonapplication;
import com.gluonhq.ignite.guice.GuiceContext;
import com.gluonhq.particle.application.ParticleApplication;
import com.google.inject.AbstractModule;
import javafx.scene.Scene;
import java.util.Arrays;
public class GluonApplication extends ParticleApplication {
private GuiceContext context = new GuiceContext(this, () -> Arrays.asList(new GuiceModule()));
public GluonApplication() {
super("Gluon Desktop Application");
context.init();
System.out.println("From within GluonApplication Constructor: " +
context.getInstance(TestClassToInject.class).testDependancy.testString
);
}
#Override
public void postInit(Scene scene) {
setTitle("Gluon Desktop Application");
}
class GuiceModule extends AbstractModule {
#Override protected void configure() {
// Use just in time injection.
}
}
}
My controller class:
package com.gluonapplication.controllers;
import com.gluonapplication.TestClassToInject;
import com.gluonhq.particle.application.ParticleApplication;
import com.gluonhq.particle.state.StateManager;
import com.gluonhq.particle.view.ViewManager;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javax.inject.Inject;
public class PrimaryController {
#Inject ParticleApplication app;
#Inject private ViewManager viewManager;
#Inject private StateManager stateManager;
#Inject private TestClassToInject testClassToInject;
#FXML
private Label label;
public void initialize() {
}
public void postInit() {
System.out.println("From within controller's postInit() method: " +
testClassToInject.testDependancy.testString
);
}
public void dispose() {
}
}
And then my two classes created as the dependancies:
package com.gluonapplication;
import javax.inject.Inject;
public class TestClassToInject {
#Inject
public TestDependancy testDependancy;
public TestClassToInject() {
}
}
package com.gluonapplication;
public class TestDependancy {
public String testString = "This is a test string";
public TestDependancy() {
}
}
And finally my Gradle file:
apply plugin: 'java'
apply plugin: 'application'
repositories {
jcenter()
maven {
url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
}
}
mainClassName = 'com.gluonapplication.GluonApplication'
dependencies {
compile 'com.gluonhq:particle:1.1.0'
compile 'com.gluonhq:ignite-guice:1.0.0'
}
The "From within GluonApplication Constructor: " +
context.getInstance(TestClassToInject.class).testDependancy.testString prints out just fine, so I think I have the dependancy classes and Guice configured OK. However, the System.out.println("From within controller's postInit() method: " + testClassToInject.testDependancy.testString); doesn't work from within the controller because the testClassToInject is null at time of use.
You can use Gluon Ignite (http://gluonhq.com/open-source/ignite/) which supports dependency injection with Dagger, Guice and Spring. Gluon Ignite is an open source project, and you can find an example in the test directory on the repository website: https://bitbucket.org/gluon-oss/ignite/src/c85197b33852/src/test/java/com/gluonhq/ignite/?at=default

Managed bean converter injection

Hi guys I have a problem with jsf managed bean and #PersistenceUnit. I'm using this converter
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import mn.bsoft.crasmonclient.model.Customer;
/**
*
* #author D
*/
#ManagedBean
#RequestScoped
#FacesConverter(value="convertToConverter")
public class ConvertToCustomer implements Converter{
#PersistenceUnit(unitName = "CrasmonClientPU")
private EntityManagerFactory entityManagerFactory;
private EntityManager em;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
try {
em = entityManagerFactory.createEntityManager();
Object ret = em.find(Customer.class, new Integer(value));
return ret;
} catch (ConverterException e) {
System.out.println(e.getFacesMessage());
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
try {
Customer pa = (Customer) value;
return String.valueOf(pa.getCustomerId());
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
}
and I got null pointer exception on EntityManagerFactory. In my faces-config file I have:
<converter>
<converter-id>convertToCustomer</converter-id>
<converter-class>crasmonclient.converter.ConvertToCustomer</converter-class>
</converter>
Did I miss something? I don't understand why getting null pointer.
Make sure in your WAR project, there is a persistence.xml file. Furthermore, it's not possible to use #ManagedBean and #FacesConverter at the same time. You need to remove #FacesConverter and <converter> to avoid confusion and use the converter exclusively as managed bean as follows:
<h:inputText converter="#{convertToCustomer} />
Besides, why don't you inject the #PersistenceContext directly:
#PersistenceContext
EntityManager em;

Error in Select box

This is my Assignemployee.jsp file code
<s:form action="AssignEmployee" name="myForm">
<s:select name="pname" list="projectlist" headerKey="0" label="Select a country" />
<s:submit/>
</s:form>
This is my projectlist.java action file
package myPack;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
public class projectlist extends ActionSupport implements ServletRequestAware {
private static final long serialVersionUID = 1L;
HttpServletRequest request;
private List<String> projectlist;
public List<String> getProjectlist() {
return projectlist;
}
public void setProjectlist(List<String> projectlist) {
this.projectlist = projectlist;
}
public void setServletRequest(HttpServletRequest request)
{
this.request = request;
}
public HttpServletRequest getServletRequest(){
return request;
}
public String getDefaultSearchEngine() {
return "yahoo.com";
}
public projectlist()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection con=DriverManager.getConnection("jdbc:mysql:///pmt","root","shree");
ps=con.prepareStatement("select * from addproject");
ResultSet res = ps.executeQuery();
while(res.next())
{
projectlist = new ArrayList<String>();
projectlist.add(res.getString("pname"));
}
ps.close();
con.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public String execute()throws Exception
{
return SUCCESS;
}
public String display() {
return NONE;
}
}
And This is struts.xml
<action name="AssignEmployee" class="myPack.projectlist" method="display">
<result name="success">assignemployee.jsp</result>
</action>
When i am running application i get an error like
SEVERE: Servlet.service() for servlet [jsp] in context with path [/PTMS] threw exception [tag 'select', field 'list', name 'pname': The requested list key 'projectlist' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location]] with root cause
tag 'select', field 'list', name 'pname': The requested list key 'projectlist' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location]
How to solve this error?
There are two problems:
Project list creation is broken, and
The first access to the form is broken.
1) You're creating a new list for every row in the result set:
while (res.next()) {
projectlist = new ArrayList<String>();
projectlist.add(res.getString("pname"));
}
This should look closer to:
projectlist = new ArrayList<String>();
while (res.next()) {
projectlist.add(res.getString("pname"));
}
It also appears you never actually call this method, although it's difficult to tell since the code is essentially illegible without indentation or any valuable whitespace. Where you call it is open to some debate; it could be in the getter itself, a prepare() method (and the action would implement Prepareable), the execute() method, etc.
These kinds of things should likely go into a service, however, as a testability aid.
2) I'm not convinced your initial visit to the JSP is being handled correctly. It should:
a) Go through a Struts 2 action,
b) Call the projectlist initializer, and
c) Forward to the JSP with the form.
If all those criteria are met, you will not get that error.

Insert a bean into a Converter

I have the following ApplicationScoped bean
package es.caib.gesma.gesman.data;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import es.caib.gesma.gesman.ejb.Dao;
#ManagedBean(name="priorityList")
#ApplicationScoped
public class PriorityList {
#EJB
Dao daoEjb;
private List<Priority> priorities = null;
public PriorityList() {
}
#PostConstruct
public void refresh() {
this.priorities = daoEjb.findPriorities();
}
public List<Priority> getPriorities() {
return this.priorities;
}
public Priority fromId(int id) {
for(Priority priority : this.priorities) {
if (priority.getId() == id) {
return priority;
}
}
return null;
}
}
I try to inject that bean inside a Converter
package es.caib.gesma.gesman.data.converter;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import es.caib.gesma.gesman.data.Priority;
import es.caib.gesma.gesman.data.PriorityList;
#ManagedBean
#ApplicationScoped
public class PriorityConverter implements Converter {
#ManagedProperty("#{priorityList}")
private PriorityList priorityList;
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
...
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
...
}
public void setPriorityList(PriorityList priorityList) {
System.out.println("SET PRIORITYLIST " + priorityList);
this.priorityList = priorityList;
}
}
Whenever I try to access the property, it is null. The setter is never called.
From this question and this one, it looks like it is not possible to inject the bean the usual way (please correct me if I am wrong). There is any alternative so I avoid having to get the entire list of values from the EJB (= database access) each time?
You can't (currently) inject dependencies into converters. However, if you can use Seam 3, the seam-faces module will enable this. You don't need to do anything special, just have the seam-faces JAR (and any of its dependencies) in the classpath and injection into converters will magically work. Just watch out for other unintended side-effects (I've noticed differences in transaction boundaries when the seam-persistence JAR is in the classpath).
I think you should be able to pull this bean out from the HttpSession (it works for me in PhaseListener with SessionScoped bean)
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext().getSession(true);
SessionForm sessionBean = (SessionForm) session.getAttribute("priorityList");
Or if I may borrow article from BalusC about JSF communication, on the bottom is described how to make a converter from ManagedBean (so you could easily inject your ApplicationScoped bean there)

Resources