Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 4, 2012 9:17 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 4, 2012 9:42 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 7, 2012 11:52 PM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 8, 2012 7:21 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 9, 2012 9:00 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 10, 2012 3:11 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Hasika Pamunuwa May 10, 2012 9:27 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 10, 2012 9:30 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 11, 2012 5:26 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 11, 2012 8:52 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 11, 2012 10:04 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 11, 2012 10:10 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 14, 2012 8:04 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 14, 2012 8:01 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 14, 2012 8:24 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 14, 2012 8:03 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 14, 2012 8:24 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 14, 2012 8:33 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 14, 2012 3:07 PM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Jon Gilmore May 15, 2012 3:40 AM
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer Neil Griffin May 16, 2012 12:24 PM
Jon Gilmore
LiferayFacesContext.getPortletInstanceId() throws null pointer
May 4, 2012 9:17 AM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

Hello,

I receive a NullPointerException when calling getPortletInstanceId(). I am using liferay-faces-portal version 3.0.0-BETA1.

LiferayFacesContext liferayFacesContext = LiferayFacesContext.getInstance();
liferayFacesContext.getPortletInstanceId();

java.lang.NullPointerException
at com.liferay.faces.portal.context.LiferayPortletHelperImpl.getPortletInstanceId(LiferayPortletHelperImpl.java:147)
at com.liferay.faces.portal.context.LiferayFacesContextImpl.getPortletInstanceId(LiferayFacesContextImpl.java:743)

Thanks for any suggestions.
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 4, 2012 9:42 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

Hi Jon,

What version of Liferay Portal are you using?

Neil
Jon Gilmore
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 7, 2012 11:52 PM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

We're using liferay 6.1
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 8, 2012 7:21 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

Ah, you need to use Liferay Faces 3.1.x (currently 3.1.0-BETA2) for Liferay 6.1

The 3.0.x version that you're using is for Liferay 6.0
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 9, 2012 9:00 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

Fixed in FACES-1212. emoticon
Jon Gilmore
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 10, 2012 3:11 AM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

Hi Neil,
Thanks for your help. I've updated my portlet to use liferay-faces-bridge-impl-3.1.0-BETA2.jar and liferay-faces-portal-3.1.0-BETA2.jar.

Unfortunately I'm still getting the following exception when running in Liferay 6.1. Can I provide you with any more information?

java.lang.NullPointerException
at com.liferay.faces.portal.context.LiferayPortletHelperImpl.getPortletInstanceId(LiferayPortletHelperImpl.java:147)
at com.liferay.faces.portal.context.LiferayFacesContextImpl.getPortletInstanceId(LiferayFacesContextImpl.java:743)

 1
 2/**
 3 * Fades out/in a portlet out from the view when visible is set to false/true. Uses the portlet id and jquery to alter the portlets encapsulating dom.
 4 */
 5 public final class FTSVisibilityRenderer extends DomBasicRenderer
 6{
 7    @Override
 8    public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
 9    {
10        ValueExpression valueExpression = uiComponent.getValueExpression("visibility");
11        FTSLiferayPortlet liferayPortlet = (FTSLiferayPortlet) valueExpression.getValue(facesContext.getELContext());
12
13        if (liferayPortlet == null)
14            LOG.warn("Unable to determine visibility from value expressions, defaulting to true.");
15
16        Boolean isVisible = ( liferayPortlet != null ? liferayPortlet.isPortletVisible() : true );
17
18        LiferayFacesContext portletFacesContext = LiferayFacesContext.getInstance();
19        if (LOG.isDebugEnabled())
20            LOG.debug("Visibility for portlet: '" + portletFacesContext.getPortletName() + "' is: " + isVisible);
21       
22        String portletId = "p_p_id_" + portletFacesContext.getPortletInstanceId() + "_";
23
24        String javascript = MessageFormat.format(FADEOUT, new Object[] {portletId});
25        if (isVisible)
26            javascript = MessageFormat.format(FADEIN, new Object[] {portletId});
27
28        JavascriptContext.addJavascriptCall(facesContext, javascript);
29    }
30
31    private static final String FADEOUT = "jQuery(''#{0}'').fadeOut(''fast'');";
32    private static final String FADEIN  = "jQuery(''#{0}'').fadeIn(''fast'');";
Hasika Pamunuwa
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 10, 2012 9:27 AM
Answer

Hasika Pamunuwa

Rank: New Member

Posts: 11

Join Date: June 21, 2010

Recent Posts

I think it'll be fixed in 3.1.0 RC1.

Following worked for me.

1
2LiferayFacesContext liferayFacesContext = LiferayFacesContext.getInstance();
3PortletRequestImpl portletRequest = (PortletRequestImpl) liferayFacesContext.getExternalContext().getRequest();
4Portlet portlet = portletRequest.getPortlet();
5String portletInstanceId = portlet.getPortletId();
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 10, 2012 9:30 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

Hasika is correct -- fixed in 3.1.0-RC1. You can grab the source from GitHub and build 3.1.0-RC1-SNAPSHOT locally for now if you like.
Jon Gilmore
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 11, 2012 5:26 AM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

3.1.0-RC1 has certainly helped. LiferayFacesContext.getPortletInstanceId() now works from within a JSF thread.

Unfortunately, I'm performing a render request via PortableRenderer.render() !! i.e. from outside a JSF thread I get the following stack trace:

2012-05-11 12:07:27,721 [http-nio-8080-exec-17] DEBUG com.liferay.faces.portal.el.ExtELResolver:debug:39 - Unable to resolve variable value=null
2012-05-11 12:07:27,737 [http-nio-8080-exec-17] DEBUG com.liferay.faces.portal.el.ExtELResolver:debug:39 - Unable to resolve variable value=null
java.lang.NullPointerException
at com.liferay.faces.portal.context.LiferayPortletHelperImpl.getPortletInstanceId(LiferayPortletHelperImpl.java:163)
at com.liferay.faces.portal.context.LiferayFacesContextImpl.getPortletInstanceId(LiferayFacesContextImpl.java:743)

This was certainly possible using edoarasframework 1.3.0 together with liferay 5.2. Do you think it will be made possible in liferay-faces?
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 11, 2012 8:52 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

Under the hood, Liferay Faces Portal has a managed-bean named Liferay that uses the JSF2 ViewScoped annotation. This has the effect of keeping data (like the current com.liferay.portal.model.Portlet instance) in-memory. For example, here's the constructor of the bean:
1public Liferay() {
2    // FACES-1212: Cache the "RENDER_PORTLET" request attribute here in the constructor since it is only
3    // available during the RENDER_PHASE of the portlet lifecycle.
4    FacesContext facesContext = FacesContext.getCurrentInstance();
5    PortletRequest portletRequest = (PortletRequest) facesContext.getExternalContext().getRequest();
6    portlet = (Portlet) portletRequest.getAttribute(WebKeys.RENDER_PORTLET);
7}


Back in the days of PortletFaces-Tools (edoarasframework 1.3.0) this bean was kept in memory with ICEfaces Extended-Request scope. This has been replaced by JSF2 ViewScoped, which apparently doesn't last long enough for your needs. If you want to use the Liferay managed bean outside of a JSF thread (and outside of a PortletRequest) like you're doing with the PortableRenderer, then my guess would be that the Liferay managed-bean would have to be kept around longer than ViewScoped permits.

I suppose one thing you could try, would be to have the following in your portlet's WEB-INF/faces-config.xml descriptor:
1<managed-bean>
2<managed-bean-name>liferay</managed-bean-name>
3<managed-bean-class>com.liferay.faces.portal.bean.Liferay</managed-bean-class>
4<managed-bean-scope>#{window}</managed-bean-scope>
5</managed-bean>


The WEB-INF/faces-config.xml is designed to "win" when there is a conflict with annotations. So by using the managed-bean syntax above, I would *think* it would cause the Liferay managed-bean to be placed in the ICEfaces WindowScope which might live long enough for your needs.
Jon Gilmore
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 11, 2012 10:04 AM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

Your suggestion does not seem to override as hoped. I tried your code sample and received the same error as before, and then even tried changing the liferay bean scope to session, which I'm sure is not advised, but it didn't help either.
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 11, 2012 10:10 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

Please checkout the source from GitHub and change the annotation in Liferay.java from @ViewScoped to @SessionScoped and let me know if that works.
Jon Gilmore
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 14, 2012 8:04 AM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

Hi again, with the liferay bean session scope set session it now complains about the headManagedBean being null:

1
22012-05-14 14:42:28,556 [http-nio-8080-exec-11] DEBUG com.liferay.faces.portal.el.ExtELResolver:debug:39 - Unable to resolve variable [headManagedBean] value=null
32012-05-14 14:42:28,556 [Message Mediator Thread] ERROR com.ftsinfo.portal.model.event.FTSPortletEventMulticastor:handle
4SessionMessage:199 - (8437da) Problem encountered message.
5java.lang.NullPointerException
6        at com.liferay.faces.portal.context.LiferayPortletHelperImpl.getPortletRequest(LiferayPortletHelperImpl.java:168)
7        at com.liferay.faces.portal.context.LiferayPortletHelperImpl.getPortlet(LiferayPortletHelperImpl.java:150)
8        at com.liferay.faces.portal.context.LiferayPortletHelperImpl.getPortletInstanceId(LiferayPortletHelperImpl.java:163)
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 14, 2012 8:01 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

The stacktrace you posted doesn't seem to mention the "Caused By" issue regarding the headManagedBean. Can you look more deeply into your stacktrace and see if it mentions a "Caused By" exception regarding HeadPhaseListener or HeadRendererBridgeImpl? Those are the two classes that call HeadManagedBean.getInstance(FacesContext).
Jon Gilmore
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 14, 2012 8:03 AM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

Also, a call to JavascriptContext.addJavascriptCall(liferayFacesContext, javascript) from a non jsf thread also results in a NullPointerException. I'm guessing this is a very similar issue.

1
2java.lang.NullPointerException
3        at com.liferay.faces.portal.context.LiferayFacesContextImpl.getExternalContext(LiferayFacesContextImpl.java:515)
Jon Gilmore
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 14, 2012 8:24 AM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

There is no other log output I'm afraid. I have DEBUG switched on, I could try TRACE if you think that will help.
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 14, 2012 8:24 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

Line 515 of LiferayFacesContextImpl currently looks like this:

1return FacesContext.getCurrentInstance().getExternalContext();


I'd like to try and make LiferayFacesContext work for you in this non-JSF-thread situation, but if the call to FacesContext.getCurrentInstance().getExternalContext() is returning null, then this may be opening a can of worms. Please put this line of code in your non-JSF-thread and let me know the output:

1System.err.println("facesContext=" + FacesContext.getCurrentInstance());


Thanks,

Neil
Jon Gilmore
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 14, 2012 8:33 AM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

FacesContext.getCurrentInstance() returns null
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 14, 2012 3:07 PM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

I spoke to my contact at ICEsoft about this, and I think I have a better understanding of what's going on now.

It makes sense that FacesContext.getCurrentInstance() returns null in a non-JSF-thread in an ICEfaces 2.x/3.x portlet. The reason why your code worked with ICEfaces 1.8 Ajax Push is because ICEfaces would create a pseudo FacesContext in a non-JSF-thread.

The reason why your code is not porting to ICEfaces 2.0/3.0 is because it doesn't create the pseudo FacesContext anymore. Instead the ICEpush mechanism is purely a notification system now, and so you will probably have to refactor your code a little. Basically, your non-JSF-thread should not be changing JSF model managed-bean values or calling anything that relies on FacesContext. When your code calls PortableRenderer.render() it will simply instruct the browser to execute a new XmlHttpRequest() that will run the Faces lifecycle. At that time, your JSF model managed-beans should determine the latest values, so that the browser's DOM will be updated accordingly.

For more information, see: http://wiki.icesoft.org/display/ICE/Ajax+Push+-+APIs
Jon Gilmore
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 15, 2012 3:40 AM
Answer

Jon Gilmore

Rank: New Member

Posts: 12

Join Date: August 17, 2010

Recent Posts

Thanks for that, it gave us a handy idea. I implemented the same code within a component for which we've defined a bespoke renderer, on the theory that it will be called within the Faces lifecycle following the PortableRenderer.render() call. Using this method we find that FacesContext.getCurrentInstance() does not return null when called from within the renderer AND JavascriptContext.addJavascriptCall works! The only issue I have within the renderer is that LiferayFacesContext.getPortletInstanceId() still throws the NullPointerException as mentioned in previous posts, although we can get around this issue quite easily.

I'm a bit worried about your statement that the non-JSF-thread should not be changing JSF model managed-bean values. I see little use in using the PortableRenderer if one cannot alter values in the managed bean and propagate them to the user, maybe I've misunderstood.

 1
 2public final class FTSVisibilityRenderer extends DomBasicRenderer
 3{
 4    @Override
 5    public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
 6    {
 7        ValueExpression valueExpression = uiComponent.getValueExpression("visibility");
 8        FTSLiferayPortlet liferayPortlet = (FTSLiferayPortlet) valueExpression.getValue(facesContext.getELContext());
 9        if (liferayPortlet == null)
10            LOG.warn("Unable to determine visibility from value expressions, defaulting to true.");
11
12        Boolean isVisible = ( liferayPortlet != null ? liferayPortlet.isPortletVisible() : true );
13
14        String portletId = "";
15        String javascript = "";
16        try {
17            //this returns a not null object
18            System.err.println("faces context get current instance: " + FacesContext.getCurrentInstance());
19        } catch (Exception e) {
20            e.printStackTrace();
21            return;
22        }
23
24        try {
25            LiferayFacesContext lfc = LiferayFacesContext.getInstance();
26            //this throws a NullPointerException
27            portletId = "p_p_id_" + lfc.getPortletInstanceId() + "_";
28        } catch (Exception e) {
29            e.printStackTrace();
30            return;
31        }
32
33        try {
34            javascript = MessageFormat.format(FADEOUT, new Object[] {portletId});
35            if (isVisible)
36                javascript = MessageFormat.format(FADEIN, new Object[] {portletId});
37
38            //this works
39            JavascriptContext.addJavascriptCall(facesContext, javascript);
40
41        } catch (Exception e) {
42            e.printStackTrace();
43            return;
44        }
45    }
46
47    private static final String FADEOUT = "jQuery(''#{0}'').fadeOut(''fast'');";
48    private static final String FADEIN  = "jQuery(''#{0}'').fadeIn(''fast'');";
49
50    private static final Logger LOG = Logger.getLogger(FTSVisibilityRenderer.class);
51}
Neil Griffin
RE: LiferayFacesContext.getPortletInstanceId() throws null pointer
May 16, 2012 12:24 PM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2097

Join Date: July 26, 2005

Recent Posts

Hi Jon,

I'm glad it's working for you now. emoticon

Regarding what you said here:
Jon Gilmore:
I'm a bit worried about your statement that the non-JSF-thread should not be changing JSF model managed-bean values. I see little use in using the PortableRenderer if one cannot alter values in the managed bean and propagate them to the user, maybe I've misunderstood.


Let me clarify -- What I meant was that, since the non-JSF-thread doesn't have the ability to do JSF things like resolve JSF managed-bean instances, it is not possible to update any bean values from your non-JSF-thread.

However, there are two things I can think of that you can do:

1. If your managed-beans are @SessionScoped, then you can call [url=http://portals.apache.org/pluto/portlet-2.0-apidocs/javax/portlet/PortletRequest.html#getPortletSession()]PortletRequest.getPortletSession() in order to get the session scope. You can then call [url=http://portals.apache.org/pluto/portlet-2.0-apidocs/javax/portlet/PortletSession.html#getAttribute(java.lang.String)]PortletSession.getAttribute(String name) from your non-JSF-thread in order to find the managed-bean instance.

2. If your managed-beans are @RequestScoped or @ViewScoped, then you can inject a @SessionScoped (see #1) managed-bean into it with a @ManagedProperty annotation.

3. You can use Spring to define some spring-beans that contain data. You can then have your non-JSF-thread get the spring-bean instance from the Spring ApplicationContext and when it comes time for your JSF managed-beans values to get called during the subsequent JSF lifecycle, the JSF managed-beans could then get values from the spring-beans. I used this in a project once and it worked great. Or you could just use Spring to manage all your beans. That would work too for everything except @ViewScoped.