netbeans icon indicating copy to clipboard operation
netbeans copied to clipboard

add new jakarta faces libraries

Open NicolaIsotta opened this issue 4 weeks ago • 1 comments

This adds new default libraries for JSF/Faces 3.0, 4.0 and 4.1 image image This also changes the frameworks wizard, now the registered libraries are only selectable if compatible, this screenshot is taken from a project targeting Tomcat 10.1/Jakarta EE 10: image

Fixes #8855


^Add meaningful description above

Click to collapse/expand PR instructions

By opening a pull request you confirm that, unless explicitly stated otherwise, the changes -

  • are all your own work, and you have the right to contribute them.
  • are contributed solely under the terms and conditions of the Apache License 2.0 (see section 5 of the license for more information).

Please make sure (eg. git log) that all commits have a valid name and email address for you in the Author field.

If you're a first time contributor, see the Contributing guidelines for more information.

If you're a committer, please label the PR before pressing "Create pull request" so that the right test jobs can run.

PR approval and merge checklist:

  1. [ ] Was this PR correctly labeled, did the right tests run? When did they run?
  2. [ ] Is this PR squashed?
  3. [ ] Are author name / email address correct? Are co-authors correctly listed? Do the commit messages need updates?
  4. [ ] Does the PR title and description still fit after the Nth iteration? Is the description sufficient to appear in the release notes?

If this PR targets the delivery branch: don't merge. (full wiki article)

NicolaIsotta avatar Dec 11 '25 16:12 NicolaIsotta

Seems like it was a license formatting issue. Hope it's ok now.

NicolaIsotta avatar Dec 13 '25 10:12 NicolaIsotta

I tried to remove the singleton from DefaultFaceletsLibraries, but it fails when the jsf impl uses the jakarta namespace:

Exception
java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    org/netbeans/modules/web/jsf/editor/facelets/mojarra/ConfigManager.publishPostConfigEvent()V @36: invokevirtual
  Reason:
    Type 'com/sun/faces/el/ELContextImpl' (current frame, stack[0]) is not assignable to 'javax/el/ELContext'
  Current Frame:
    bci: @36
    flags: { }
    locals: { 'org/netbeans/modules/web/jsf/editor/facelets/mojarra/ConfigManager', 'javax/faces/context/FacesContext', 'javax/faces/application/Application', 'com/sun/faces/el/ELContextImpl' }
    stack: { 'com/sun/faces/el/ELContextImpl', 'java/lang/Class', 'javax/faces/context/FacesContext' }
  Bytecode:
    0000000: b800 574c 2bb6 01ce 4d01 2bc0 005d b601
    0000010: d2a6 0072 bb01 d659 2cb6 01d8 b701 de4e
    0000020: 2d12 582b b601 e12b b601 e73a 0401 1904
    0000030: a500 0c2d 1904 b601 ebb6 01f1 2cb6 01f5
    0000040: 3a05 1905 be9e 0036 bb01 f959 2db7 01fb
    0000050: 3a06 1905 3a07 1907 be36 0803 3609 1509
    0000060: 1508 a200 1919 0715 0932 3a0a 190a 1906
    0000070: b901 fe02 0084 0901 a7ff e62b c000 5d2d
    0000080: b602 042c 2b13 0207 1301 d92c b602 09b1
    0000090:                                        
  Stackmap Table:
    full_frame(@60,{Object[#11],Object[#88],Object[#473],Object[#482],Object[#492]},{})
    full_frame(@94,{Object[#11],Object[#88],Object[#473],Object[#482],Object[#492],Object[#841],Object[#505],Object[#841],Integer,Integer},{})
    full_frame(@123,{Object[#11],Object[#88],Object[#473],Object[#482],Object[#492],Object[#841]},{})
    chop_frame(@131,3)
at org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport._findLibraries(FaceletsLibrarySupport.java:396)
at org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport.findLibraries(FaceletsLibrarySupport.java:270)
at org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport.getNamespaceLibraryMapping(FaceletsLibrarySupport.java:173)
at org.netbeans.modules.web.jsf.editor.JsfSupportImpl.getLibrary(JsfSupportImpl.java:216)
at org.netbeans.modules.web.jsf.editor.HtmlSourceTask.run(HtmlSourceTask.java:133)
at org.netbeans.modules.web.jsf.editor.HtmlSourceTask.run(HtmlSourceTask.java:51)
at org.netbeans.modules.parsing.impl.TaskProcessor.callParserResultTask(TaskProcessor.java:561)
at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.run(TaskProcessor.java:786)
at org.openide.util.lookup.Lookups.executeWith(Lookups.java:288)
at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.execute(TaskProcessor.java:702)

[catch] at org.netbeans.modules.parsing.impl.TaskProcessor$CompilationJob.run(TaskProcessor.java:663) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1403) at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45) at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287) at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2018)

Should I create a JakartaConfigManager which uses the new classes? Not sure if possible because the class uses com.sun.faces classes coming from javax version...

NicolaIsotta avatar Dec 16 '25 19:12 NicolaIsotta

The problem I see here is, that not only the interface classes from JSF/Faces are used, but also the implementation classes. That works as long as the implementations always match the interfaces. That does not work anymore (javax.* vs. jakarta.* package namespaces).

So yes I think you are right. We need to isolate the implementations more. Maybe the approach taken for JSP can be adapted. Starting point is here: https://github.com/apache/netbeans/blob/master/enterprise/web.jspparser/src/org/netbeans/modules/web/jspparser/JspParserImpl.java

The idea is there: the javax/jakarta specific part is built into a separate jar. For parsing a class loader is created, that makes the modules abstraction classes available, adds the java/jakarta specific parts and also includes the corresponding API modules. The javax/jakarta specific part parses the JSP and maps the data into the abstraction classes. These are then returned and used by the surrounding code. The javax/jakarta specific part is thus confined into the special class loader.

For JSP the javax/jakarta specific code (https://github.com/apache/netbeans/tree/master/enterprise/web.jspparser/extsrc) exists only once in the jakarta variant, but is build for javax by replacing the references with the corresponding javax variants.

matthiasblaesing avatar Dec 19 '25 20:12 matthiasblaesing