0

I'm trying to use the ManagedProperty annotation to Dependency Injection to another ManagedBean, but I always getting a NullPointerException. I will try to describe how my application works.

This is a PDF generator. First, I have xhtml page that has a Tabbed Pane. In each tab I use <ui:include> tag. All of these beans have ViewScope.

In first Tab I have title inputText and description textArea fields, and it's strange beacuse this fields are working well, even if I do not use DI.

My problem starts when I go to another Tab, and I want to add some additional information/text whatever.

My app works like this: I write some text to inputText field (1), then I press "Ready" (2) button that passes this object to the factory, then I press "Print" (3) button to generate .pdf file. In this picture You can see PanelInneBean and ContainerBean areas.

enter image description here

Let me show my source:

@ManagedBean(name="inne")
@ViewScoped
public class PanelInneBean extends AbstractPanel implements Serializable {
    private static final long serialVersionUID = 1L;
    private final int CODE = 4;
    private boolean use;
    private String tytul, opis;
    private PdfFactory pdf;

    @PostConstruct
    private void init() {
    pdf = PdfFactory.getPdfObject();
    use = false;
    }

    public PanelInneBean() {
    }

    public boolean getUse() {
    return use;
    }

    public String getTytul() {
    return tytul;
    }

    public void setTytul(String tytul) {
    this.tytul = tytul;
    }

    public String getOpis() {
    return opis;
    }

    public void setOpis(String opis) {
    this.opis = opis;
    }

    public int getCode() {
    return CODE;
    }

    private void add() {
    use = true;
    }

    public void addBean() {
    add();
    pdf.addElement(this);
    System.out.println("InnePanel after pdf.addElement() this.opis:" + this.opis);
    }
}

Factory source:

@ManagedBean(name="factory")
@SessionScoped
public class PdfFactory implements Serializable {
//.............
private InneP inn = new InneP() //without new does not work too;
//.............

    public int addElement(PdfElement element) {
    pdfType = true;
    if (element.getUse()) {
        elementList.add(element);
        return 1;
    }
    return 0;
    }

//.............

public List<Element> getDocumentBody() throws DocumentException {
    initSignature();
    List<Element> list = new ArrayList<Element>();
    list.add(createDocDate());
    list.add(Chunk.NEWLINE);
    for (PdfElement p : elementList) {
        if (p.getUse()) {
        switch (p.getCode()) {
//............
        case 4:
            list.addAll(inn.generatePharse());
            break;
        }
        }
    }
    list.addAll(sF.generatePharse());
    return list;
    }

last InneP source (this class generate Paragraps to print) in this class i'm getting NPE:

@ManagedBean
@RequestScoped
public class InneP {
    private List<Element> list = new ArrayList<Element>();
    private Font font;

    @ManagedProperty("#{inne}")
    private PanelInneBean panelInneBean;

    public InneP(){}

    public InneP(Font font) {
    this.font = font;
    }

    public void setPanelInneBean(PanelInneBean inne) {
    this.panelInneBean = inne;
    }

    public List<Element> generatePharse() {
    if (panelInneBean.getTytul().length() > 0) {
        System.out.println("drukowanie tytulu");
        list.add(createTitle(panelInneBean.getTytul()));
        list.add(Chunk.NEWLINE);
    }
    if (panelInneBean.getOpis().length() > 0) {
        list.add(createDescription(panelInneBean.getOpis()));
        list.add(Chunk.NEWLINE);
    }

    return list;
    }

    private Paragraph createTitle(String tytul) {
    System.out.println("inne tytul: " + tytul);
    font.setStyle(Font.NORMAL);
    Paragraph t = new Paragraph(tytul, font);
    t.setAlignment(Element.ALIGN_LEFT);
    return t;
    }

    private Paragraph createDescription(String opis) {
    System.out.println("inne opis:" + opis);
    font.setStyle(Font.BOLD);
    Paragraph d = new Paragraph(opis, font);
    d.setAlignment(Element.ALIGN_LEFT);
    return d;
    }

}

The print button just adds the list to the for loop and print all Paragraphs; I use iText lib and OpenFaces to generate Tabbed Pane.

I hope that I wrote enough information.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
insict
  • 861
  • 2
  • 11
  • 19
  • In `private InneP inn` you have `private InneP inn`. Where do you initialize that field? In `InneP` class you don't have `@ManagedBean` annotation so it is not managed bean, so you are creating it manually with `new`? – partlov Mar 10 '13 at 19:04
  • I forgot to add annotations to InneP ManagedBean now added and still getting NPE. No I not use `new` word; – insict Mar 10 '13 at 19:12
  • http://stackoverflow.com/questions/6244965/sessionscoped-does-not-work-when-adding-named ? – MarianP Mar 10 '13 at 19:14
  • Update question to be like your code. Also I told your private field `inn` doesn't have `ManagedProperty`. Just update that all, and edit your question. – partlov Mar 10 '13 at 19:15
  • inn variable in class PdfFactory is nowhere initialized to work ManagedProperty well. – insict Mar 10 '13 at 19:17
  • Well, if your `inn` is not initialized you will have in `inn.generatePharse()` NPE also. `inn` will always be `null` here. Also `panelInneBean` will be null if `InneP` is not managed bean. – partlov Mar 10 '13 at 19:21
  • ok, I edited post, now I initialize inn in PdfFactory, and adds @ManagedBean to InneP but it still throws NPE – insict Mar 10 '13 at 19:24
  • You initialize it as a plain object, it is not added into the container. It should be '@ManagedProperty private InneP inn' in PdfFactory bean. – MarianP Mar 10 '13 at 19:36
  • but `InneP` and `PanelInneBean` are two different objects – insict Mar 10 '13 at 19:38
  • I don't understand your last comment. You may not create managed bean on your own, at least not the usual way as a common object using 'new' keyword. You need to use ManagedBean annotation to define that a class is intended to be used as a managed bean. Than use ManagedProperty to make container create a new managed bean instance (at the appropriate time, depending on the scope), or fetch an existing one. – MarianP Mar 10 '13 at 19:47
  • ok, I understand, but in which class add ManagedProperty annotation? – insict Mar 10 '13 at 20:00

1 Answers1

0

First if you want to bean be managed by JSF you can instantiate it manually (with new), you have to use @ManagedProperty to let container instantiate and set your property (like you did with panelInneBean field, for example). In your case this will not work, because you want to use request scoped bean in session scoped bean, so you can't inject it. Reason is because during the life of one session scoped bean there will be many request scoped beans instances. So you need to get your InneP instance in other ways.

In methods where you want to use InneP instance you have to manually obtain it, don't assign it on some class field, use local variable as you will have another instance in every request:

InneP inneP = (InneP) context.getApplication().getExpressionFactory()
        .createValueExpression(FacesContext.getCurrentInstance().getELContext(), "#{inneP}", InneP.class)
            .getValue(FacesContext.getCurrentInstance().getELContext());
partlov
  • 13,789
  • 6
  • 63
  • 82