add new jakarta faces libraries
This adds new default libraries for JSF/Faces 3.0, 4.0 and 4.1
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:
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:
- [ ] Was this PR correctly labeled, did the right tests run? When did they run?
- [ ] Is this PR squashed?
- [ ] Are author name / email address correct? Are co-authors correctly listed? Do the commit messages need updates?
- [ ] 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)
Seems like it was a license formatting issue. Hope it's ok now.
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...
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.