Forums de discussion

Namespace ID and UIViewRoot ID differ

J S, modifié il y a 11 années.

Namespace ID and UIViewRoot ID differ

Junior Member Publications: 31 Date d'inscription: 11/04/12 Publications récentes
Hi,

I'm trying to use findComponent to find this:

A5128:j_idt7:portletForm:dropForm:sketcherSettings:j_id27

A5128 is the portlet namespace.

However I get this exception:

<f:ajax> contains an unknown id ':A5128:j_idt7:portletForm:dropForm:sketcherSettings:j_id19' - cannot locate it in the context of the component left_id

When I debug the findComponent code I find that it is finding an instance of UIViewRootBridgeImpl to use as the starting point, as I would expect for an absolute search like this.

However, findComponent fails because when it attempts to resolve the A5128 segment it compares A5128 to the id of UIViewRootBridgeImpl , but it returns _jpfcpncuivr_A5128_A5128 so obviously the find fails.

Can anyone explain what I'm doing wrong?

Thanks,

John.
thumbnail
Neil Griffin, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Liferay Legend Publications: 2655 Date d'inscription: 27/07/05 Publications récentes
From the error message I think you might have a leading colon (separator char) at the beginning of your search expression. Are you calling findComponent like this?
UIComponent uiComponent =
    someOtherComponent.findComponent(":A5128:j_idt7:portletForm:dropForm:sketcherSettings:j_id19");

According to the JavaDocs for UIComponentBase.findComponent(String), "The leading separator character will be stripped off, and the remainder of the search expression will be treated as a "relative" search expression [...]"
You might have to try a few different things, but perhaps you could try leaving off the portlet namespace:
UIComponent uiComponent =
    someOtherComponent.findComponent(":j_idt7:portletForm:dropForm:sketcherSettings:j_id19");

Also, the Liferay Faces Portal dependency has a nice singleton feature called LiferayFacesContext which decorates the FacesContext ThreadLocal singleton. You can use it like this:
LiferayFacesContext liferayFacesContext = LiferayFacesContext.getInstance();

It has some nice convenience methods on it that might help you solve the problem:
	/**
	 * Traverses the component tree starting at the specified UIComponent parent and returns the first UIComponent child
	 * that contains the specified partialClientId.
	 */
	public abstract UIComponent matchComponentInHierarchy(UIComponent parent, String partialClientId);

	/**
	 * Traverses the component tree associated with the UIViewRoot of this FacesContext and returns the first
	 * UIComponent child that contains the specified partialClientId.
	 */
	public abstract UIComponent matchComponentInViewRoot(String partialClientId);
J S, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Junior Member Publications: 31 Date d'inscription: 11/04/12 Publications récentes
You can use : at the beginning, it means search from the root instead of the first NamingContainer parent. I have to do this as I need to refer to components that are in different NamingContainers. This code in UIComponentBase.findComponent shows how it is used:

        // Identify the base component from which we will perform our search
        UIComponent base = this;
        if (expr.charAt(0) == sepChar) {
            // Absolute searches start at the root of the tree
            while (base.getParent() != null) {
                base = base.getParent();
            }
            // Treat remainder of the expression as relative
            expr = expr.substring(1);
        } else if (!(base instanceof NamingContainer)) {
            // Relative expressions start at the closest NamingContainer or root
            while (base.getParent() != null) {
                if (base instanceof NamingContainer) {
                    break;
                }
                base = base.getParent();
            }
        }


The problem I am having is occuring in mojarra library code (2.1.3) and so I can't change it to use the methods you suggest.

I don't understand why the UIViewRootBridgeImpl method is returning the id " _jpfcpncuivr_A5128_A5128 " but this doesn't match the clientIds I see in the generated HTML, the portlet div is:


My code is generating some AjaxBehaviors and using the clientIds in the render list, these IDs match what I see in the generated HTML, but not what the UIViewRootBridgeImpl getId method returns.

Is there a mismatch between getClientId and getId perhaps?

Thanks,

John
thumbnail
Neil Griffin, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Liferay Legend Publications: 2655 Date d'inscription: 27/07/05 Publications récentes
Please paste the code that shows your call to findComponent, especially the string that you are passing.
J S, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Junior Member Publications: 31 Date d'inscription: 11/04/12 Publications récentes
The id being passed is
:A5128:j_idt7:portletForm:dropForm:sketcherSettings:j_id11


The code, from com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer is

// Returns the resolved (client id) for a particular id.
    private static String getResolvedId(UIComponent component, String id) {

        UIComponent resolvedComponent = component.findComponent(id);
        if (resolvedComponent == null) {
            // RELEASE_PENDING  i18n
            throw new FacesException(
                "<f:ajax> contains an unknown id '"
                + id
                + "' - cannot locate it in the context of the component "+component.getId());
        }

        return resolvedComponent.getClientId();
    }</f:ajax>


I should add that the exception occurs whilst rendering a response to an Ajax request
thumbnail
Neil Griffin, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Liferay Legend Publications: 2655 Date d'inscription: 27/07/05 Publications récentes
Can you upload/attach a simple portlet that reproduces the problem? I'd be happy to take a look at it.
J S, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Junior Member Publications: 31 Date d'inscription: 11/04/12 Publications récentes
I'll see what I can do, I'm porting over an application to liferay so have to try and extract the appropriate parts, will take a while.

John
J S, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Junior Member Publications: 31 Date d'inscription: 11/04/12 Publications récentes
I've attached a sample project, it has one page which contains 2 forms.

The Click me first button adds an AjaxBehavior to the second button. The Behaviour adds the second form to it's render list.

When the first button is clicked the error occurs. It's the same error that happens in our application. In our application the click is updating a properties pane in the page which is programatically created, hence why the behaviour is added this way.

You can see form the error that the ID it can't find is something like A7585:f1 , but when find component is invoked it is expecting the root ID to be off the form

id = PORTLET_NAMESPACE_ID_PREFIX + ec.encodeNamespace("") + "_" + id;


which is generated in PortletNamingContainerUIViewRoot

Is that enough information?

Thanks,

John

Pièces jointes:

J S, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Junior Member Publications: 31 Date d'inscription: 11/04/12 Publications récentes
Just a bit more info,

I added this to the bean method:
        UIViewRoot viewRoot = context.getViewRoot();
        String clientId = viewRoot.getClientId();
        UIComponent uiComponent = viewRoot.getChildren().get(0);
        logger.info("Root clientId: " + clientId +", firstChild: " + uiComponent.getClientId() + "[ " + uiComponent.getClass().getName() + " ]");


which results in the output:
14:50:56,515 INFO  [SampleBean:72] Root clientId: _jpfcpncuivr_A7585_A7585, firstChild: A7585:j_idt2[ com.sun.faces.facelets.compiler.UIInstructions ]


It doesn't seem right to me that the root client ID is different than the root part of the first child's clientId?

John
thumbnail
Neil Griffin, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Liferay Legend Publications: 2655 Date d'inscription: 27/07/05 Publications récentes
Thanks for the sample portlet. You were exactly right! I just fixed this bug in FACES-1206.

Unfortunately, even with the fix for the bridge, there is a bug in Mojarra that is preventing your portlet from executing correctly, See: JAVASERVERFACES-2049. I recommend that you convert your sample portlet into a sample webapp and attach it to the Mojarra issue so that they will be able to reproduce the issue.
J S, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Junior Member Publications: 31 Date d'inscription: 11/04/12 Publications récentes
Great!

This does fix the issue I was having in our application. I am using Mojarra 2.1.3 so maybe that's why I don't see the Mojarra issue? I'd previously found that when I upgraded to 2.1.7 I had problems so parked the upgrade for later.

Thanks,

John.
thumbnail
Neil Griffin, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Liferay Legend Publications: 2655 Date d'inscription: 27/07/05 Publications récentes
Glad to hear that the issue is fixed for you -- I think I was using Mojarra 2.1.3-b02 when I saw the problem.
J S, modifié il y a 11 années.

RE: Namespace ID and UIViewRoot ID differ

Junior Member Publications: 31 Date d'inscription: 11/04/12 Publications récentes
I get the same error as you in my sample portlet. The original app is different in that the component that has the behaviour added to it is added dynamically through code. I think dynamic components are restored in a different order so that might be why the original app does suffer from the issue.

I see there is a sample added to the mojarra issue now, so hopefully they'll fix it.

Thanks,

John