faces-migrate
SkillAI & modelsMigrate a Jakarta Faces project from one version to another (e.g. JSF 2.3 to Faces 4.1)
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the faces-migrate skill
What this skill tells your AI
The instructions your AI receives, as published by omnifaces/claude-faces-expert in .claude/skills/faces-migrate/SKILL.md and read by ahel’s review.
Version 1.6.0
Migrate the current project to Jakarta Faces $ARGUMENTS (if no argument, ask the developer for the target version).
Step 1: Detect Current Version
Determine the current Faces version from:
pom.xmlorbuild.gradledependencies (look forjavax.faces,jakarta.faces,jsf-api,myfaces-api).faces-config.xmlversion attribute.- XML namespaces in XHTML files (
java.sun.com= JSF 1.0+,xmlns.jcp.org= JSF 2.2+,jakarta.faces= Faces 4.0+). - Package imports in Java files (
javax.faces= JSF 1.x/2.x vsjakarta.faces= Faces 3.0+).
Also determine the runtime type:
- Full EE server (WildFly, GlassFish, TomEE, Payara, WebSphere, Liberty, etc.): Faces, CDI, BV, EJB, JPA, JAX-RS, etc. are all provided by the runtime; the project should depend on the Java EE / Jakarta EE API artifact with
<scope>provided</scope>, not on standalone implementations. - Barebones servlet container (Tomcat, Jetty, Undertow, etc.) or framework (Spring Boot): Tomcat only provides Servlet, JSP, EL, WebSocket, and JASIC; everything else (Faces, CDI, BV, JSTL, etc.) must be installed/bundled separately with the application.
When updating dependencies in migration steps, update the appropriate artifact:
- On a full EE server: update the EE API version and ensure the target server version supports the target Faces version.
- Java EE 8 (JSF 2.3):
javax:javaee-web-api:8.0with<scope>provided</scope> - Jakarta EE 9 (Faces 3.0):
jakarta.platform:jakarta.jakartaee-web-api:9.0.0with<scope>provided</scope> - Jakarta EE 10 (Faces 4.0):
jakarta.platform:jakarta.jakartaee-web-api:10.0.0with<scope>provided</scope> - Jakarta EE 11 (Faces 4.1):
jakarta.platform:jakarta.jakartaee-web-api:11.0.0with<scope>provided</scope>
- Java EE 8 (JSF 2.3):
- On a barebones servlet container: update the standalone Faces implementation version directly (e.g.
org.glassfish:jakarta.facesfor Mojarra,org.apache.myfaces.core:myfaces-implfor MyFaces); do NOT usejavaee-apiorjakarta.jakartaee-apias a substitute because it will allow compiling against APIs that the servlet container doesn't actually provide.
Report the detected version and runtime type, and confirm with the developer before proceeding.
Step 2: Determine Migration Path
Based on source → target version, apply the relevant steps below. Multiple steps may apply for multi-version jumps (e.g. JSF 2.0 → Faces 4.1 requires all intermediate steps).
Migration Steps
JSF 1.x → JSF 2.0+ (major rewrite)
This is a significant migration; confirm scope with developer before proceeding.
- Replace JSP files with Facelets (XHTML).
- Replace
<f:view>,<f:subview>with Facelets templating (<ui:composition>,<ui:define>). - Replace
<managed-bean>entries infaces-config.xmlwith@ManagedBean+ scope annotations (will be migrated to@Namedin later step). - Replace
<navigation-rule>entries infaces-config.xmlwith return values from action methods or?faces-redirect=true. - Replace
javax.faces.webapp.FacesServletURL pattern/faces/*or*.facesor*.jsfwith*.xhtml.
JSF 2.x → JSF 2.3 (incremental)
- Update
pom.xmlto JSF 2.3 dependency. - Replace
@ManagedBean+@javax.faces.bean.*Scopedwith@Named+@javax.enterprise.context.*Scoped. @ViewScoped: replacejavax.faces.bean.ViewScopedwithjavax.faces.view.ViewScoped.- Replace
@javax.faces.bean.ManagedPropertyon managed beans with@Inject. - Replace
@javax.faces.bean.ManagedPropertyon unmanaged variables with@javax.faces.annotation.ManagedProperty. - FacesServlet: ensure URL pattern is
*.xhtml; remove legacy*.jsf,*.faces,/faces/*mappings. - Update
faces-config.xmlversion to2.3.<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd" version="2.3" > - Update
*.taglib.xmlversion to2.3.<facelet-taglib xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_3.xsd" version="2.3" > - Update XML namespaces from
java.sun.comtoxmlns.jcp.org(if on JSF 2.2+). - Use HTML5 doctype
<!DOCTYPE html>(if on JSF 2.2+). - If the project has a
web.xmland its declared version lags behind Servlet 4.0 (Java EE 8), update it. If it still carries a legacy DTD-basedDOCTYPEdeclaration (pre-Servlet 2.4), drop it entirely — the XML Schemaxmlns/xsi:schemaLocationform below replaces it.<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" > - Ensure
beans.xmlexists inWEB-INF/, and update it to CDI 2.0 (Java EE 8) when it lags behind. Once aversionattribute is present,bean-discovery-modeis required alongside it. Preferannotated:@Namedplus a CDI scope is a bean defining annotation, so Faces beans are discovered either way.<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd" version="2.0" bean-discovery-mode="annotated" > - Review for new 2.3 features to adopt: https://arjan-tijms.omnifaces.org/p/jsf-23.html
JSF 2.3 → Faces 3.0 (Jakarta EE 9, namespace rename)
This is purely a package rename; no behavioral changes.
- Update
pom.xmlto Jakarta Faces 3.0 dependency. - Rename ALL
javax.faces.*imports tojakarta.faces.*in Java files. - Rename ALL
javax.servlet.*tojakarta.servlet.*. - Rename ALL
javax.inject.*tojakarta.inject.*. - Rename ALL
javax.enterprise.*tojakarta.enterprise.*. - Rename ALL
javax.annotation.*tojakarta.annotation.*. - Rename ALL
javax.validation.*tojakarta.validation.*. - Rename ALL
javax.persistence.*tojakarta.persistence.*(if JPA is used). - Rename ALL
javax.ejb.*tojakarta.ejb.*(if EJB is used). - Rename ALL
javax.ws.rs.*tojakarta.ws.rs.*(if JAX-RS is used). - Update
web.xmlcontext param names fromjavax.faces.*tojakarta.faces.*. - Move any
javax/faces/Messages*.propertiesfrom the project's own resources tojakarta/faces/, keeping the locale suffixes (Messages_it.properties,Messages_nl_BE.properties, etc.). - Rename the keys inside that bundle from
javax.faces.*tojakarta.faces.*(e.g.javax.faces.component.UIInput.REQUIRED→jakarta.faces.component.UIInput.REQUIRED). - Rename the same keys in the bundle declared by
<message-bundle>infaces-config.xmland in all its locale variants, if any. The declared name is a base name; the file names are project-chosen and stay as-is, only the keys change. - Rename
javax.validation.constraints.*.messagekeys tojakarta.validation.constraints.*.messageinValidationMessages*.properties, if present. - NOTE: bundles declared by
<resource-bundle>infaces-config.xmlhold application-defined keys and need no key rename. - FacesServlet: ensure URL pattern is
*.xhtml; remove legacy*.jsf,*.faces,/faces/*mappings. - Update
faces-config.xmlnamespace and version to3.0.<faces-config xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_3_0.xsd" version="3.0" > - Update
*.taglib.xmlnamespace and version to3.0.<facelet-taglib xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facelettaglibrary_3_0.xsd" version="3.0" > - NOTE: XHTML namespaces stay the same (
xmlns.jcp.org) in Faces 3.0; they only change in 4.0. - Use HTML5 doctype
<!DOCTYPE html>(if not already). - If the project has a
web.xmland its declared version lags behind Servlet 5.0 (Jakarta EE 9), update it.<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0" > - Update
beans.xmlnamespace and version to CDI 3.0 (Jakarta EE 9), keeping the existingbean-discovery-mode, which stays required next toversion.<beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd" version="3.0" bean-discovery-mode="annotated" >
Faces 3.0 → Faces 4.0+ (Jakarta EE 10+, spec overhaul)
- Update
pom.xmlto Jakarta Faces 4.0 dependency. - Update XHTML namespaces from
xmlns.jcp.orgtojakarta.facesURNs:http://xmlns.jcp.org/jsf/html→jakarta.faces.htmlhttp://xmlns.jcp.org/jsf/core→jakarta.faces.corehttp://xmlns.jcp.org/jsf/facelets→jakarta.faces.faceletshttp://xmlns.jcp.org/jsf/composite→jakarta.faces.compositehttp://xmlns.jcp.org/jsf/passthrough→jakarta.faces.passthroughhttp://xmlns.jcp.org/jsf→jakarta.faceshttp://xmlns.jcp.org/jsp/jstl/core→jakarta.tags.core
- Remove
xmlns="http://www.w3.org/1999/xhtml"from XHTML files; since Faces 4.0 it is always implied. - Remove any remaining
@ManagedBeanusage (removed in Faces 4.0); replace with@Named+ CDI scope. - Remove any
javax.faces.bean.*imports (package removed entirely). - FacesServlet: ensure URL pattern is
*.xhtml; remove legacy*.jsf,*.faces,/faces/*mappings. - Update
faces-config.xmlversion to4.0.<faces-config xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_4_0.xsd" version="4.0" > - Update
*.taglib.xmlversion to4.0.<facelet-taglib xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facelettaglibrary_4_0.xsd" version="4.0" > - Use HTML5 doctype
<!DOCTYPE html>(if not already). - If the project has a
web.xmland its declared version lags behind Servlet 6.0 (Jakarta EE 10), update it.<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" version="6.0" > - Make
bean-discovery-modeexplicit inbeans.xmlBEFORE bumping it to CDI 4.0. Up to CDI 3.0 an empty or version-lessbeans.xmlmeantall; since CDI 4.0 the attribute is optional and defaults toannotated. Every bean without a bean defining annotation then stops being discovered at runtime, and nothing fails at build time. Report the choice: keepallto preserve current behavior, or move toannotatedand annotate the beans that need it. - Update
beans.xmlversion to CDI 4.0 (Jakarta EE 10), keeping thebean-discovery-modedecided above.<beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd" version="4.0" bean-discovery-mode="annotated" > - Review for new 4.0 features to adopt: https://balusc.omnifaces.org/2021/11/whats-new-in-faces-40.html
Faces 4.0 → Faces 4.1 (Jakarta EE 11, incremental)
- Update
pom.xmlto Jakarta Faces 4.1 dependency. - Update
faces-config.xmlversion to4.1.<faces-config xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_4_1.xsd" version="4.1" > - Update
*.taglib.xmlversion to4.1.<facelet-taglib xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facelettaglibrary_4_1.xsd" version="4.1" > - If the project has a
web.xmland its declared version lags behind Servlet 6.1 (Jakarta EE 11), update it.<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_1.xsd" version="6.1" > - Update
beans.xmlversion to CDI 4.1 (Jakarta EE 11), keeping the existingbean-discovery-mode.<beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_1.xsd" version="4.1" bean-discovery-mode="annotated" > - When the project overrides the standard message bundle (
jakarta/faces/Messages*.properties) or declares a<message-bundle>, report the keys that Faces 4.1 adds so the developer can supply translations. Faces 4.1 adds two, for the newUUIDConverter:jakarta.faces.converter.UUIDConverter.UUIDjakarta.faces.converter.UUIDConverter.UUID_detail
- Full state saving is deprecated for removal since 4.1 and is removed in Faces 5.0, along with both its context params in
web.xml. Migrating them off now is what makes the next jump a version bump rather than a rewrite:jakarta.faces.PARTIAL_STATE_SAVING: remove it when set totrue, which is the default since 2.0. When set tofalse, report it rather than removing it; the application is running on full state saving and removing the param flips it onto partial state saving, which surfaces any custom component that does not save its state correctly; fix those first.jakarta.faces.FULL_STATE_SAVING_VIEW_IDS: report the listed view IDs, which need the same treatment per view.
- Replace the
ActionSource2types, all deprecated for removal since 4.1; their members moved to theActionSourcecounterpart:jakarta.faces.component.ActionSource2→jakarta.faces.component.ActionSourcejakarta.faces.view.ActionSource2AttachedObjectHandler→jakarta.faces.view.ActionSourceAttachedObjectHandlerjakarta.faces.view.ActionSource2AttachedObjectTarget→jakarta.faces.view.ActionSourceAttachedObjectTarget
- Review for new 4.1 features to adopt: https://balusc.omnifaces.org/2024/06/whats-new-in-faces-41.html
Step 3: Execute
For each applicable migration step:
- Show the developer what will change (file count, type of changes).
- Confirm before proceeding.
- Apply changes file by file.
- After all changes, report a summary.
Step 4: Verify
After migration:
- Check for any remaining old-version references (grep for old package names, old namespaces, old annotations).
- Check for any remaining
javax.keys in*.propertiesfiles and for a leftoverjavax/faces/resource directory; these fail silently rather than at build time. - Check that
faces-config.xml,web.xmlandbeans.xmleach declare a version no higher than the Faces, Servlet resp. CDI API the runtime supplies, and no lower than needed for the descriptor features in use. - Verify
pom.xml/build.gradlehas no conflicting dependency versions. - Suggest running
/faces-reviewto catch any remaining issues.
Important
- ALWAYS confirm with the developer before making changes.
- For large projects, offer to do a dry run first (report only, no changes).
- When migrating across multiple versions (e.g. JSF 2.0 → Faces 4.1), apply steps in order; do NOT skip intermediate steps.
- Preserve existing code style (indentation, line endings, import ordering).
- Third-party libraries (PrimeFaces, OmniFaces, etc.) may also need version upgrades; flag these but let the developer decide.
Signals
- GitHub stars
- 25
- Forks
- 1
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
faces-migrate- Source
- github.com/omnifaces/claude-faces-expert