Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Jonathan Locht
JSF app with CDI in Liferay 7
July 4, 2017 1:00 AM
Answer

Jonathan Locht

Rank: New Member

Posts: 7

Join Date: July 4, 2017

Recent Posts

Hello,

I'm currently trying to migrate our existing JSF app from Liferay 6.2 to Liferay 7.
We are using JSF along with CDI on jboss 6.4. and the app also includes liferay hooks such as servlet filters and themes.

The app is packaged in an ear archive that we used to deploy directly in the jboss deployment folder - not going through the liferay/deploy directory.
My first question is: Can we still deploy that way with Liferay 7 (ear + jboss deployment folder)?

However I tried to follow the instructions from this post: https://web.liferay.com/community/forums/-/message_boards/message/89548463.
I generated a new liferay project with jsf and cdi and I'm now trying to add my code in bits by bits.

My understanding is that I cannot use jboss dependencies yet but I should include all jars inside the WEB-INF/lib folder of my war.
Is that correct ?

I noticed that all the cdi examples (like the applicant portlet) are using weld-servlet.jar instead of cdi-portlet-bridge-shared-6.2.0.2.jar.
Is that required for Liferay 7 ?

The first issue I'm facing is that the CDI injections don't work if the injected class is defined inside a jar in the WEB-INF/lib.
I get this error :
1 org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type UserSession with qualifiers @Default_  at injection point [UnbackedAnnotatedField] @Inject private com.sopra.banking.workstation.ui.web.controller.OperationalPositionListController.userSession_  at com.sopra.banking.workstation.ui.web.controller.OperationalPositionListController.userSession(OperationalPositionListController.java:0)_ [Sanitized]

The UserSession class is defined in one of the jars and the OperationalPositionListController class is directly defined in the war.
If I move that UserSession from the jar to the war classes it works.
Is there a way around this because I can't move all the classes ?

In the app, I've also included my theme that we used to apply using this property in the portal-ext :
# <themeName>_WAR_<contextroot>
default.theme.id=workstation_WAR_soprabankingworkstationweb
Now this does not work with Liferay7 because the context root is the name of the war file instead of what's defined in the jboss-web.xml.
Does Liferay 7 ignore the jboss-web.xml ?

Any advice or guidance would be much appreciated.

Best Regards,
Jonathan
Neil Griffin
RE: JSF app with CDI in Liferay 7
July 5, 2017 12:42 PM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2499

Join Date: July 26, 2005

Recent Posts

Hi Jonathan,

Jonathan Locht:
The app is packaged in an ear archive that we used to deploy directly in the jboss deployment folder - not going through the liferay/deploy directory. My first question is: Can we still deploy that way with Liferay 7 (ear + jboss deployment folder)?


Liferay Portal 7 does not support EAR deployment (with embedded portlet WARs) via the app server. Instead, portlet WARs must be deployed via the $LIFERAY_HOME/deploy directory. The reason why this is necessary is that the WAR must undergo transformation to a WAB (OSGi Web Application Bundle) during deployment via the WAB Generator.

Jonathan Locht:
However I tried to follow the instructions from this post: https://web.liferay.com/community/forums/-/message_boards/message/89548463. I generated a new liferay project with jsf and cdi and I'm now trying to add my code in bits by bits.


This is the right approach -- start by generating a new project with one of the archetypes found at the www.liferayfaces.org home page. Then gradually migrate code into the project.

Jonathan Locht:
My understanding is that I cannot use jboss dependencies yet but I should include all jars inside the WEB-INF/lib folder of my war. Is that correct?


Yes, that is correct because the app server (JBoss/WildFly in this case) is not aware of any of the deployed portlet WARs, since they become WABs managed by the OSGi container.

Jonathan Locht:
I noticed that all the cdi examples (like the applicant portlet) are using weld-servlet.jar instead of cdi-portlet-bridge-shared-6.2.0.2.jar. Is that required for Liferay 7?


The cdi-portlet-bridge-shared-6.2.0.2jar dependency should not be necessary if you are using weld-servlet-2.3.3.Final.jar

Jonathan Locht:
The first issue I'm facing is that the CDI injections don't work if the injected class is defined inside a jar in the WEB-INF/lib.
I get this error ... Is there a way around this because I can't move all the classes?


Try adding bean-discovery-mode="all" to beans.xml -- here is an example.

Jonathan Locht:
Does Liferay 7 ignore the jboss-web.xml?


I will ask some of my colleagues to answer that question in a subsequent post in this thread.

Kind Regards,

Neil
David H Nebinger
RE: JSF app with CDI in Liferay 7
July 5, 2017 12:55 PM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 13020

Join Date: September 1, 2006

Recent Posts

I hate to contradict my good friend Neil, and typically he trumps me, but...

Jonathan Locht:
The app is packaged in an ear archive that we used to deploy directly in the jboss deployment folder - not going through the liferay/deploy directory.
My first question is: Can we still deploy that way with Liferay 7 (ear + jboss deployment folder)?


Yes, but not like you think. Liferay 7 CE / Liferay DXP does not rely on the application server anymore, so war files are not really used any longer.

That said, we do have the "deployment helper". This is a specialized war file that contains all of the module jars and wars to deploy to Liferay 7 CE / Liferay DXP and upon deployment, will extract the module jars and wars to the $LIFERAY_HOME/deploy folder. So this can, in fact, get bundled into an ear because as a war file the deployment helper doesn't really have a context.

The deployment helper war is meant to be used to support the centralized management consoles of weblogic and websphere, but it should be just as usable for your ear deployment scenario.

In the app, I've also included my theme that we used to apply using this property in the portal-ext :
# <themeName>_WAR_<contextroot>
default.theme.id=workstation_WAR_soprabankingworkstationweb
Now this does not work with Liferay7 because the context root is the name of the war file instead of what's defined in the jboss-web.xml.
Does Liferay 7 ignore the jboss-web.xml ?


Since the theme is actually hosted within the Liferay OSGi container (and not deployed as a war to the app server), the jboss-web.xml file is neither used or recognized.








Come meet me at the 2017 LSNA!
David H Nebinger
RE: JSF app with CDI in Liferay 7
July 5, 2017 2:24 PM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 13020

Join Date: September 1, 2006

Recent Posts

Note that using the deployment helper to package and deploy jars and wars, even when bundled into an ear, would not allow for using @EJB or other JEE annotations or other JEE features.

The deployment helper would only allow for packaging in an ear format for deployment only and would not enable any JEE functionality.









Come meet me at the 2017 LSNA!
Jonathan Locht
RE: JSF app with CDI in Liferay 7
July 10, 2017 4:07 AM
Answer

Jonathan Locht

Rank: New Member

Posts: 7

Join Date: July 4, 2017

Recent Posts

Hi Neil,

I tried adding bean-discovery-mode="all" to the beans.xml but it made no difference.

So I took the demo/jsf-cdi-applicant-portlet sources and added an injection in the ApplicantModelBean like this :

1
2    @Inject
3    private TestInjectBean testInjectBean;


And the new class is just

 1
 2package com.liferay.faces.demos.bean;
 3import java.io.Serializable;
 4import javax.enterprise.context.RequestScoped;
 5import javax.inject.Named;
 6
 7@Named
 8@RequestScoped
 9public class TestInjectBean
10    implements Serializable
11{
12    private static final long serialVersionUID = 1L;
13
14}


The TestInjectBean is in another project jar.
That jar also has a bean.xml and is included in the WEB-INF/lib of the jsf-cdi-applicant-portlet war.

I'm still getting he error :

ERROR [Refresh Thread: Equinox Container: a0e681ea-4565-0017-13af-de170e242069][com_liferay_portal_osgi_web_wab_extender:97] WELD-001408: Unsatisfied dependencies for type TestInjectBean with qualifiers @Default_ at injection point [BackedAnnotatedField] @Inject private com.liferay.faces.demos.bean.ApplicantModelBean.testInjectBean_ at com.liferay.faces.demos.bean.ApplicantModelBean.testInjectBean(ApplicantModelBean.java:0)_


I think something is wrong with the CDI injection from lib.
Has any of you tried that configuration ?

Thanks,
Jonathan
Jonathan Locht
RE: JSF app with CDI in Liferay 7
July 10, 2017 4:25 AM
Answer

Jonathan Locht

Rank: New Member

Posts: 7

Join Date: July 4, 2017

Recent Posts

Thanks David,

I found that I could use the property
Web-ContextPath: /myContextRoot
inside the liferay-plugin-package.properties file.
The theme name is now correctly populated.

We do use EJB in our project.
If we can't deploy the ear in Liferay how can we manage the EJB ?
Would it be a right approach to split the project into one war for the web part (deployed in Liferay) and one ear for the EJB part (that we would just put in the jboss deployment folder) ? Would it be possible to call the EJB from the war then ?

Regards,
Jonathan
David H Nebinger
RE: JSF app with CDI in Liferay 7
July 10, 2017 5:58 AM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 13020

Join Date: September 1, 2006

Recent Posts

Jonathan Locht:
We do use EJB in our project.
If we can't deploy the ear in Liferay how can we manage the EJB ?
Would it be a right approach to split the project into one war for the web part (deployed in Liferay) and one ear for the EJB part (that we would just put in the jboss deployment folder) ? Would it be possible to call the EJB from the war then ?


I don't know that it is going to work... All of the module jars (and even war files are converted to wabs) run underneath Liferay's OSGi container, and as such I don't think they actually have access to other entities in the app container, but honestly I haven't tried this at all.

I see them as two separate containers, one is the app server and the other is OSGi. Liferay has built in some bridging to allow pieces of the OSGi container to get access to the Liferay code running in the app server, but I don't know if the same is true for accessing anything else in the app server.







Come meet me at Devcon 2017 or 2017 LSNA!
Neil Griffin
RE: JSF app with CDI in Liferay 7
July 10, 2017 4:04 PM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2499

Join Date: July 26, 2005

Recent Posts

Hi Jonathan,

Thank you for bringing the WELD-001408 error to our attention. I have been able to reproduce it. It is associated with the following warning from Weld:

WARN [Bootstrap:105] WELD-ENV-000031: The bean archive reference bundleresource://532.fwk345489975:10/META-INF/beans.xml cannot be handled by any BeanArchiveHandler

Solving the problem will require a contribution from Liferay to the Weld project, so that weld-servlet.jar will be able to discover the annotated beans properly in an OSGI environment. I will incorporate that into our development calendar.

For now, I am experimenting with a CDI Extension to see if that can be used as a workaround. I will report back here when I have results.

Kind Regards,

Neil
Jonathan Locht
RE: JSF app with CDI in Liferay 7
July 10, 2017 11:32 PM
Answer

Jonathan Locht

Rank: New Member

Posts: 7

Join Date: July 4, 2017

Recent Posts

Hi Neil,
I'm looking forward to hearing from you.
Thank you so much for your time.
Jonathan
Neil Griffin
RE: JSF app with CDI in Liferay 7
July 11, 2017 9:43 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2499

Join Date: July 26, 2005

Recent Posts

Hi Jonathan,

I figured out a workaround using Dynamic CDI Producers.

Attached you will find a simple maven project that contains TestInjectBean.java and an associated Dynamic CDI Producer named TestInjectBeanProducer.java

The drawback of this approach is that you need to create a Dynamic CDI Producer for each bean that you might want to @Inject. Also you will need to register each one in TestExtension.java

But if the friendly folks at JBoss are willing to merge a future fix into the codebase for weld-servlet, then you will be able to simply remove the dynamic producers and things should continue to work.

Kind Regards,

Neil
Attachments: otherbeans.zip (8.2k)
Jonathan Locht
RE: JSF app with CDI in Liferay 7
July 13, 2017 2:30 AM
Answer

Jonathan Locht

Rank: New Member

Posts: 7

Join Date: July 4, 2017

Recent Posts

Does that mean we can't/shouldn't use EJB with Liferay 7 ?
Would you recommand another technology ?
Jonathan Locht
RE: JSF app with CDI in Liferay 7
July 13, 2017 2:41 AM
Answer

Jonathan Locht

Rank: New Member

Posts: 7

Join Date: July 4, 2017

Recent Posts

Hi Neil,

Thank you very much for providing the workaround.
Unfortuntely I don't think it'll be able applicable in our app.
Because we have dozens of injections comming from many different libraries (deltaspike for example).
I would have to create and register the producer for each one of them.

Regards,
Jonathan
Jonathan Locht
RE: JSF app with CDI in Liferay 7
September 21, 2017 4:20 AM
Answer

Jonathan Locht

Rank: New Member

Posts: 7

Join Date: July 4, 2017

Recent Posts

Hi Neil,

My colleague was given the advise (thanks to Huage Chen) to use jandex as a workaround.
But I'm not sure I understand the point.
Would it be used to programatically register and generate the producers ?

Did you get any update on the WELD issue ?

Regards,
Jonathan