3

Please have a look at the following JSF page and at the definition of the managed bean class which it references.

When I run my app and load the page I get the results shown in the "Good Results" screen shot. Note that the page is displaying data and that the "Hello World" string printed by the bean's constructor appears in the console.

If I alter the bean's definition by commenting out the definition of the "junk" integer (near the top) then I get the results shown in the "Bad Results" screen shot. Now there is no data and, most tellingly, the "Hello World" string does not appear in the console. No errors are reported to the console. The page is being rendered but it appears as though the JSF engine has decided that it does not like the bean's definition and is therefore not going to use it (the constructor is not called).

I have tried mightily to produce a Minimal, Complete, and Verifiable example. I eliminated several forms from the JSF page (you can observe that much of the bean's code is no longer being referenced by the JSF page). I eliminated JPA from the picture by creating the DummyDataAccessService class. I tried to eliminate the use of one or more of my own custom classes (Order, Patient, Product, DataAccessService, and DummyDataAccessService) but I could not: almost any alteration of the bean's definition produces the same strange behavior that results from removing the definition of the "junk" member variable.

I created a custom logging.properties file which bumped the level to ALL. The logging produced by the Good vs. Bad cases were close to the same. The two "Logging Differences" screen shots below reveal the primary differences.

I do not know how to explore this further. I don't know enough to even conjecture what might be going on. Any clue or recommendation on a course of action will be greatly appreciated.

JSF Page

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">

<h:head>
    <h:outputStylesheet library="default" name="css/style.css"  />
    <title>Managed Bean Problem</title>
</h:head>
<h:body> 
    <h3 class="title">Managed Bean Problem</h3>
    <h:outputText value="&#160;" />

    <table align="center" width="600">
        <tr><td><h:form>
            <h:dataTable value="#{orderController.table}" var="order" styleClass="demo" columnClasses="columns, columns">
                <h:column>
                    <f:facet name="header">
                        <h:column>
                            <h:outputText value="Patient"></h:outputText>
                        </h:column>
                    </f:facet>
                    <h:outputText value="#{order.patient.fullName}"></h:outputText>
                </h:column>

                <h:column>
                    <f:facet name="header">
                        <h:column>
                            <h:outputText value="Product"></h:outputText>
                        </h:column>
                    </f:facet>
                    <h:outputText value="#{order.product.name}"></h:outputText>
                </h:column>

                <h:column>
                    <f:facet name="header">
                        <h:column>
                            <h:outputText value="Actions"></h:outputText>
                        </h:column>
                    </f:facet>
                    <h:panelGrid columns="1">
                        <h:commandLink value="delete" action="#{orderController.delete}">
                            <f:setPropertyActionListener target="#{orderController.target}" value="#{order}" />
                        </h:commandLink>
                    </h:panelGrid>
                </h:column>
            </h:dataTable>
        </h:form></td></tr>
    </table>
</h:body>

Order Controller Managed Bean

package com.rvaessen.dmescripts.controllers;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.model.SelectItem;

import com.rvaessen.dmescripts.model.*;

@ManagedBean
public class OrderController {

private int junk; // Leave it in; Good. Comment it out; Bad.

private DataAccessService dataService = new DummyDataAccessService();

public OrderController() {
    System.out.println("Hello, World");
}

@PostConstruct
public void init() {
    initPatients();
    initProducts();
    initOrders();
}

// ********************************* The Orders Table ***************************************

private Order target;
private List<Order> table;

private void initOrders() { table = dataService.getOrders(); }

public List<Order> getTable() { return table; }

public void setTarget(Order order) { target = order; }

public String delete() {
    dataService.removeOrder(target);
    table.remove(target);
    return null;
}

// ********************************* Add New Order ***************************************
// NOTE: The Add New Order methods are no longer referenced by the JSF page

private Order newOrder;

public String addNew() {
    newOrder = new Order();
    return null;
}

public String save() {
    dataService.addOrder(newOrder, patient, product);
    table.add(newOrder);   
    cancel();

    return null;
}

public String cancel() {
    newOrder = null;
    return null;
}

public boolean getAddingNew() { return newOrder != null; }

/************************ The Patients Menu **********************************/
// NOTE: The Patients Menu methods are no longer referenced by the JSF page

private Patient patient;
private List<Patient> patients;

private void initPatients() {
    patients = dataService.getPatients();
    if (patients.size() > 0) patient = patients.get(0);
}

public List<SelectItem> getPatients() {
    List<SelectItem> list = new ArrayList<SelectItem>();
    patients.forEach(patient -> list.add(new SelectItem(patient.getId(), patient.getFullName())));
    return list;
}

public Long getPatientId() {
    return patient == null ? 0 : patient.getId();
}

public void setPatientId(Long id) {
    patients.forEach(patient -> {
        if (patient.getId() == id) {
            this.patient = patient;
        }
    });
}

/************************ The Products Menu **********************************/
// NOTE: The Products Menu methods are no longer referenced by JSF page

private Product product;
private List<Product> products;

private void initProducts() {
    products = dataService.getProducts();
    if (products.size() > 0) product = products.get(0);
}

public List<SelectItem> getProducts() {
    List<SelectItem> list = new ArrayList<SelectItem>();
    if (patient != null) {
        products.forEach(product -> {
            if (product.getInsurance().equals(patient.getInsurance())) {
                list.add(new SelectItem(product.getId(), product.getName()));
            }
        });
    }
    return list;
}

public Long getProductId() {
    return product == null ? 0 : product.getId();
}

public void setProductId(Long id) {
    products.forEach(product -> {
        if (product.getId() == id) {
            this.product = product;
        }
    });
}
}

Good Results

Good Results

Bad Results

Bad Results

Log Differences 1

Log Differences 1

Log Differences 2

enter image description here

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
Verticon
  • 2,129
  • 11
  • 24
  • Logs tell that the server hotdeployed instead of restarted. Not all servers are good at that. Have you already tried restarting? – BalusC Apr 18 '18 at 06:05
  • @BalusC. Thank you for responding. Yes. And, to be sure, I just now did it again. I stopped server, removed deployed app, cleaned project, left junk definition in place, run on server => Good Result. Repeated but with junk definition commented out => Bad Result.. – Verticon Apr 18 '18 at 11:41
  • @BalusC Just to be clear: there is nothing "special" about the 'junk' variable. I can make the same thing happen by commenting out a section of the bean's code. It is quite maddening! – Verticon Apr 18 '18 at 11:46
  • @BalusC Re. my last comment - I just now tried it. I commented out everything (including junk) except the segment of code that is actually referenced by the JSF page (The segment labeled as 'The Orders Table"). Result => Good. – Verticon Apr 18 '18 at 11:58
  • @BalusC Hey Bauke, I guess that this one is just too weird, heh? – Verticon Apr 18 '18 at 22:00
  • The problem is not in the code, but in the build and runtime environment. Not JSF related. – BalusC Apr 19 '18 at 06:32
  • Yeah. Well that brings me to my next step which is to recreate the project from scratch. Wish me luck. Thank you for your attention and for all of your very helpful postings! – Verticon Apr 19 '18 at 13:45
  • I recreated the project (Eclipse -> New -> Dynamic Web App) with a JSF 2.2 facet and then added the JSF pages, beans, and data definitions. The issue remains. Quite discouraging. – Verticon Apr 21 '18 at 14:26
  • @BalusC Are you sure that this is not JSF related? Did you look at the "Log Differences 1" screen shot? What could possibly account for the JSF engine not attempting to retrieve the table row values from the managed bean? – Verticon Apr 21 '18 at 20:29
  • I keep thinking about it. The tags in the JSF page are being processed, the page is being rendered. How is this possible? How can the JSF engine be doing that without reporting some sort of error regarding the bean? – Verticon Apr 21 '18 at 21:37
  • Because bean is optional for output. If you follow this guide as to installing Mojarra in Tomcat, you should be set: https://github.com/javaserverfaces/mojarra/blob/master/README.md – BalusC Apr 22 '18 at 11:12
  • @BalusC It works! I am so relieved (albeit a bit gun shy now). Thank you very much for helping me. Do you want to post an answer and collect my bounty (I expect that is how it works; I've never done a bounty before)? Note to other readers - this link came in handy for installing CDI: https://stackoverflow.com/questions/18995951/how-to-install-and-use-cdi-on-tomcat/19003725#19003725 – Verticon Apr 23 '18 at 15:05
  • Still unclear what your original problem was. Perhaps JAR libraries got messed up? I gather that you're manually carrying around JARs. – BalusC Apr 23 '18 at 15:10
  • Yes, manual JARs. I would like to use Maven but have encountered hiccups. I tried this [https://crunchify.com/how-to-create-dynamic-web-project-using-maven-in-eclipse/] but, upon reaching the end, I could not access the index page. I'll probably try again. I have various confusions - if I use maven then which Eclipse configurations do I no longer use: java build path? facets? others? I'm fairly ignorant (albeit pretty smart) - trying to learn, Really appreciate you, dude! – Verticon Apr 23 '18 at 19:54
  • My best guess would be that you've in some way ended up with duplicate JSF API classes, e.g. by having placed two or more from these in your webapp: `jsf-api.jar`, `javax.faces.jar` or `javaee.jar`. You'll then guaranteed end up with "weird" trouble as described in https://stackoverflow.com/a/8081384 – BalusC Apr 26 '18 at 18:40

1 Answers1

0

This issue was never solved. It was made to go away by recreating the Eclipse project from scratch; simultaneously upgrading to JSF 2.3 / CDI 1.2.

Verticon
  • 2,129
  • 11
  • 24