Search code examples
javajsfjsf-2

JSF 2.0: @ResourceDependency does not work when adding UIComponent programmatically


@ResourceDependency(library = "component/myComponent", name = "myComponent1.css")
public class MyComponent1 extends UIComponentBase {

    public void encodeBegin(FacesContext context) throws IOException {
        MyComponent2 comp2 = new MyComponent2();
        getChildren().add(comp2);
    }

}

@ResourceDependency(library = "component/myComponent", name = "myComponent2.css")
public class MyComponent2 extends UIComponentBase {

    // ...

}

myComponent1.css gets included into page, myComponent2.css does not.

Feature? Bug? Configuration issue?

It there programmatic way to add resources to maybe workaround this?

Running Mojarra 2.0.2


Solution

  • I know this was asked 10 months ago, but I've been facing this same issue. Your resource problem here is caused by the fact that you are using "new" to instantiate your child component. Instead, you should use context.getApplication().createComponent("MyComponentType"), "MyComponentType" being whatever you specified as the value in @FacesComponent annotation. The application parses the annotations while it creates the component, not when it is rendering. Using new deprives the application from it's opportunity to handle the annotations. Unfortunately, this doesn't actually resolve the issue, it should, but it doesn't.

    If you add:

    UIComponent headFacet = context.getViewRoot().getFacet("javax_faces_location_HEAD");
    if (headFacet == null) {
        System.out.println("No Head Facet");
    } else {
        System.out.println("Head Children: " + headFacet.getChildCount());
        for (UIComponent c : headFacet.getChildren()) {
            System.out.println(c.getRendererType());
            System.out.println(c.getAttributes().get("name"));
        }
    }
    

    to your encodeBegin method you will be able to see that the Resources have actually been added (example adding the PrimeFaces FileUpload as a child):

    INFO: Head Children: 4
    INFO: javax.faces.resource.Stylesheet
    INFO: fileupload/fileupload.css
    INFO: javax.faces.resource.Script
    INFO: jquery/jquery.js
    INFO: javax.faces.resource.Script
    INFO: core/core.js
    INFO: javax.faces.resource.Script
    INFO: fileupload/fileupload.js
    

    unfortunately, they still never get rendered, it is as if the component has a different view root than the page it is ultimately rendered on. I'm still looking into this further before report any bugs. I am currently running mojarra 2.0.6, I may try it on 2.2 to see if the issue is resolved.

    Update: Tested on Mojarra 2.1.3 and 2.2-SNAPSHOT. It does not work on either. I have added an issue to the Mojarra Issue Tracker

    Update Again: The people over at Mojarra have informed me that the encodeBegin is not the place to try adding components. They have pointed me to this blog posting, which describes how to "safely" do it.