Quarkus: Extension: JSF for native mode?

Created on 6 Jan 2020  路  25Comments  路  Source: quarkusio/quarkus

Describe the extension
In quarkus, the view layer can only be created by static html with client side frameworks (e.g. react, angular). Those frameworks also provide server side rendering (SSR). However, for _java developers_ those things can also be done by JSF (Jakarta Server Faces). Quarkus provides support for servlet (by undertow), web.xml and CDI.

Is there an easy way to provide support for JSF (for jvm AND native mode)? If native mode is impossible for JSF, then feel free to close this issue.

Interested in this extension, please +1 via the emoji/reaction feature of GitHub (top right).

kinextension-proposal triagwontfix

Most helpful comment

@nimo23 M2 now supports even native images ;) have fun

All 25 comments

We won't support JSF in Quarkus itself but you can talk with @tandraschko here: https://github.com/tandraschko/quarkus-myfaces .

NOTE: i moved this to the JSF implementation MyFaces and we already did a release.
A sample application is here: https://github.com/apache/myfaces/tree/master/extensions/quarkus/showcase

Native is currently not supported and i dont have time to work on it. Feel free to contact me if you would like to invest many hours to get it working ;)

@tandraschko can you add this extension to https://github.com/quarkusio/quarkus-platform or add the extension at least to maven central? Actually, users must build from source to consume this quarkus extension.

Quarkus Platform aggregates extensions from Quarkus Core and those developed by the community

the extension is in maven central ;)
https://search.maven.org/search?q=myfaces-quarkus

@tandraschko Which artifact must I add to my pom.xml? myfaces-quarkus, myfaces-quarkus-deployment or myfaces-quarkus-runtime?

Adding

<dependency>
    <groupId>org.apache.myfaces.core.extensions</groupId>
    <artifactId>myfaces-quarkus</artifactId>
    <version>2.3-next-M1</version>
    <type>pom</type>
</dependency>

to my pom.xml does not download anything.

Btw, can you change artifactId to quarkus-myfaces or quarkus-jsf to comply with official naming scheme of quarkus extensions?

i dont play to change the naming (but the correct naming would be quarkus-myfaces) as i don't know the project structure of quarkus extensions that good.
But feel free to create a issue in MyFaces Jira, so we can discuss the changes in detail and you can easily provide a PR.

also, just for your knowledge: it's a M1, now it's the right time to discuss some changes.
Also please dont expect a 100% bugfree version.
Any help is welcome here.

@nimo23 M2 now supports even native images ;) have fun

@tandraschko wow that's fanstastic news. Thanks for your effort, I will use the JSF-extension in the next time when switching the view layers from wildfly to quarkus..

@tandraschko Awesome work, appreciate the effort!

I tried it out and bumped into a few issues, but eventually got it to work. I described my issues here:
https://github.com/quarkusio/quarkus/issues/7269#issuecomment-610863225 hopefully that can be of use :)

Here's the sample I used: https://github.com/newk5/quarkus-jsf

@tandraschko @newk5 H Guys! I checked both your projects and getting the same 'Forbidden' message on the index page (the log looks good).

Building/running using Java 14 (OpenJDK Runtime Environment AdoptOpenJDK (build 14+36)), tried to run in GraalVM (graalvm-ce-java11-20.0.0) - same thing.

Did you call Index.xhtml in the Url?
Root/Welcomefile is a missing feature 馃槄

I didn't (and feel incredibly stupid :) Thanks!

you did a great job, thanks you

@tandraschko It doesn't seem like jsf files (.xhtml) are tracked in dev mode, so no changes are detected. Is there anything that can be configured to include them?

Thomas, I'm also having problem with dataList:

listsBean.getTheList() is never called for some reason.

1) hhmm, never tried that
If MyFaces is running in development mode (you should see in the console on startup), it always reloads the xhtml from the classpath. Everything else is up to quarkus. @gsmet any idea?

2) if you can put your sample on github, i can check it

After changing javax.faces.PROJECT_STAGE to Development (copy pasted Production from somewhere) all the .XHTML files are life reloaded (silently but reloaded:) Thanks for the hint!

Going to create reproducer for 2.

@tandraschko I'm getting this exception when running my app using java -jar target/service-0.0.1-SNAPSHOT-runner.jar, works as expeced in dev mode:
Quarkus 1.7.0.Final
MyFaces: 2.3-next-M3 (same for 2.3-next-M2)
Primefaces: 8.0

org.apache.myfaces.view.facelets.el.ContextAwareELException: javax.el.ELException: javax.faces.FacesException: java.lang.IllegalAccessException: Attempt to lookup caller-sensitive method using restricted lookup object at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getValue(ContextAwareTagValueExpression.java:108) at javax.faces.component._DeltaStateHelper.eval(_DeltaStateHelper.java:338) at javax.faces.component.UIOutput.getValue(UIOutput.java:69) at org.apache.myfaces.renderkit.RendererUtils.getValue(RendererUtils.java:331) at org.apache.myfaces.renderkit.RendererUtils.getStringValue(RendererUtils.java:173) at org.apache.myfaces.renderkit.html.base.HtmlTextRendererBase.renderOutput(HtmlTextRendererBase.java:86) at org.apache.myfaces.renderkit.html.base.HtmlTextRendererBase.encodeEnd(HtmlTextRendererBase.java:76) at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:649) at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:530) at org.primefaces.component.column.Column.renderChildren(Column.java:78) at org.primefaces.component.datatable.DataTableRenderer.encodeCell(DataTableRenderer.java:1455) at org.primefaces.component.datatable.DataTableRenderer.encodeRow(DataTableRenderer.java:1373) at org.primefaces.component.datatable.DataTableRenderer.encodeRows(DataTableRenderer.java:1269) at org.primefaces.component.datatable.DataTableRenderer.encodeTbody(DataTableRenderer.java:1196) at org.primefaces.component.datatable.DataTableRenderer.encodeTbody(DataTableRenderer.java:1145) at org.primefaces.component.datatable.DataTableRenderer.encodeRegularTable(DataTableRenderer.java:432) at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:363) at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:95) at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:649) at javax.faces.component.UIData.encodeEnd(UIData.java:1649) at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:88) at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:70) at org.primefaces.component.outputpanel.OutputPanelRenderer.encodeMarkup(OutputPanelRenderer.java:74) at org.primefaces.component.outputpanel.OutputPanelRenderer.encodeEnd(OutputPanelRenderer.java:48) at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:649) at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:530) at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:526) at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:526) at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:526) at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1781) at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:316) at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:122) at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:241) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:209) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63) at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:67) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:247) at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:56) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:111) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:108) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$10$1.call(UndertowDeploymentRecorder.java:567) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:152) at io.undertow.server.handlers.HttpContinueReadHandler.handleRequest(HttpContinueReadHandler.java:43) at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$1.handleRequest(UndertowDeploymentRecorder.java:114) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:290) at io.undertow.server.DefaultExchangeHandler.handle(DefaultExchangeHandler.java:18) at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$6$1.run(UndertowDeploymentRecorder.java:398) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452) at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29) at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29) at java.base/java.lang.Thread.run(Thread.java:832) at org.jboss.threads.JBossThread.run(JBossThread.java:479) Caused by: javax.el.ELException: javax.faces.FacesException: java.lang.IllegalAccessException: Attempt to lookup caller-sensitive method using restricted lookup object at org.apache.myfaces.el.resolver.LambdaBeanELResolver.getValue(LambdaBeanELResolver.java:75) at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:62) at org.apache.el.parser.AstValue.getValue(AstValue.java:169) at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190) at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getValue(ContextAwareTagValueExpression.java:100) ... 73 more Caused by: javax.faces.FacesException: java.lang.IllegalAccessException: Attempt to lookup caller-sensitive method using restricted lookup object at org.apache.myfaces.core.api.shared.lang.PropertyDescriptorUtils.getLambdaPropertyDescriptors(PropertyDescriptorUtils.java:217) at org.apache.myfaces.core.api.shared.lang.PropertyDescriptorUtils.getPropertyDescriptors(PropertyDescriptorUtils.java:110) at org.apache.myfaces.core.api.shared.lang.PropertyDescriptorUtils.getCachedPropertyDescriptors(PropertyDescriptorUtils.java:86) at org.apache.myfaces.el.resolver.LambdaBeanELResolver.getPropertyDescriptor(LambdaBeanELResolver.java:138) at org.apache.myfaces.el.resolver.LambdaBeanELResolver.getValue(LambdaBeanELResolver.java:71) ... 77 more Caused by: java.lang.IllegalAccessException: Attempt to lookup caller-sensitive method using restricted lookup object at java.base/java.lang.invoke.MethodHandles$Lookup.findBoundCallerLookup(MethodHandles.java:2834) at java.base/java.lang.invoke.MethodHandles$Lookup.unreflect(MethodHandles.java:2489) at org.apache.myfaces.core.api.shared.lang.PropertyDescriptorUtils.createLambdaPropertyDescriptor(PropertyDescriptorUtils.java:173) at org.apache.myfaces.core.api.shared.lang.PropertyDescriptorUtils.getLambdaPropertyDescriptors(PropertyDescriptorUtils.java:209) ... 81 more

did you try a snapshot? we already fixed some bugs since M3

@tandraschko works with the snapshot!

I recently gave it another try with primefaces 8 on quarkus 1.8.1 Final, MyFaces-2.3-M4, JDK 11 and I just noticed I can't change the primefaces theme. No matter what I change it to on web.xml it seems to be always using primefaces luna-amber theme. I also can't seem to enable primefaces' font-awesome when I set it to true on web.xml. @tandraschko any extra configuration I need to be doing on my end? Or is this currently not supported?

EDIT: Apologies, I just noticed I had my web.xml in the wrong directory. It's working perfectly.

Was this page helpful?
0 / 5 - 0 ratings