2

I have two ViewScoped CDI beans A and B and one JSF page. One bean (B) is injected into the other (A). Both are accessed directly from the JSF page. After some debugging I found that the instance of B injected into A is not the same as the instance of B accessed from the JSF page.

A:

package newpackage;

import java.io.Serializable;

import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@ViewScoped
public class A implements Serializable {
  @Inject
  B b;

  public int getValueB() {
    int bb = b.getValueB();
    return bb; // <- break here
  }
}

and B:

package newpackage;

import java.io.Serializable;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class B implements Serializable {
  Logger logger = Logger.getAnonymousLogger();
  int randomNumber;

  public B() {
    logger.info("Constructor B called");
  }

  @PostConstruct
  public void init() {
    SecureRandom random = new SecureRandom();
    randomNumber = random.nextInt();

    logger.log(Level.INFO, "init B called: {0}", randomNumber);
  }

  public int getValueB() {
    return randomNumber;
  }
}

and the JSF page:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  </head>
  <h:body>
    <h:outputText value="#{a.valueB}"/>
    <h:outputText value="#{b.valueB}"/>
  </h:body>
</html>

The instance of B injected into A (A.b) is not the same as the instance of B accessed directly from the JSF page (b.valueB). My expectation was they would be the same, since they're accessed at the same time on the same page. Is there an explanation for this? Was my expectation wrong?

Set a breakpoint at the line with the comment 'break here'. Now observe something peculiar: The value of the variable bb is a big random number; however, the value of A.b.randomNumber is 0. How can that be?

user1785730
  • 3,150
  • 4
  • 27
  • 50
  • from which package is he @ViewScoped taken from? – Maciej Kowalski Jan 20 '17 at 13:17
  • import javax.faces.view.ViewScoped; – user1785730 Jan 20 '17 at 13:29
  • Your Jsf Version? – jklee Jan 20 '17 at 15:03
  • How do you know they are different and how they are accessed the same time? [mcve] please – Kukeltje Jan 20 '17 at 15:23
  • And including information about the container you're using would be helpful. – John Ament Jan 20 '17 at 18:11
  • I have glassfish 4.1.2 and mojarra 2.2.13. – user1785730 Jan 23 '17 at 10:05
  • @Kukeltje: In the debugger: The memory address was different and a value I was inspecting was too. By the 'same time' I just meant during the time the page under question was loaded in the browser. – user1785730 Jan 23 '17 at 10:09
  • Your code does not show 'same time' access, that is where the clarification should be. E.g. does `a.getValueA()` effectively do a `return b.getValueB()`? How is this value 'set'... etc... Again... [mvce] otherwise helps stops here unfortunately – Kukeltje Jan 23 '17 at 10:17
  • @Kukeltje: I've turned the code snippets into a minimal example. – user1785730 Jan 23 '17 at 10:56
  • I guess you are using `h:body` instead of `body` tag – perissf Jan 23 '17 at 11:12
  • 1
    @perissf: You mean `h:head` instead of `head` since `body` works in most of the cases and a missing `h:head` can result in a lot of problems – Kukeltje Jan 23 '17 at 15:42
  • 1
    in a, implement a `getValueB() {return b.getValueB())` and add a ``. What does that show? Keep in mind that 'memory addresses' are dangerous to look at since cdi uses proxies!) – Kukeltje Jan 23 '17 at 15:45
  • @Kukeltje: sure, thanks for the clarification – perissf Jan 23 '17 at 15:48
  • @Kukeltje: I implemented a.valueB and it prints a 'B'. The memory addresses of B in a.valueB and b.valueB are still different. – user1785730 Jan 24 '17 at 14:27
  • Memory addresses of the strings?Create a random value of b in a @PostConstruct annotated method instead of a fixed value, how often is that called. Print those. Are they identical? Add constructors, how often are those called? Please do some basic debugging. – Kukeltje Jan 24 '17 at 14:44
  • Thanks for the hints, I've updated the code. As to your questions: I meant the memory addresses of the instances of B. The constructor of B is called twice; the @PostConstruct method however only once. The outputed random numbers are identical. – user1785730 Jan 25 '17 at 14:52
  • Please note that I've also updated my question at the bottom. – user1785730 Jan 25 '17 at 14:53
  • 1
    _"The outputed random numbers are identical."_ Then everything works as expected... ! _"The value of the variable bb is a big random number; however, the value of A.b.randomNumber is 0. How can that be?"_ Noticed this to once in my project. This is a debugger/cdi/injection related issue I think. 0 is the default value for an int and the debugger does not resolve the method call in a good way and shows 'wrong' information. – Kukeltje Jan 25 '17 at 17:14

0 Answers0