Skip to content

Commit 2c285d5

Browse files
authored
Migrate Mojarra and Glassfish JSF dependencies to Jakarta Faces (#1040)
* Migrate Mojarra (com.sun.faces) and Glassfish JSF dependencies to Jakarta Faces The JSF 2.x to Jakarta Faces migration recipes only handled javax.faces:javax.faces-api, missing the widely-used Mojarra (com.sun.faces:jsf-api, com.sun.faces:jsf-impl) and Glassfish (org.glassfish:javax.faces) artifacts. This caused ClassCastException at runtime when upgrading to Spring 6 because the JSF runtime stayed on javax.el while Spring 6 uses jakarta.el. Adds ChangeDependency rules for com.sun.faces and org.glassfish:javax.faces in the Faces 3.x migration, and UpgradeDependencyVersion for org.glassfish:jakarta.faces in the Faces 4.x migration. Fixes moderneinc/customer-requests#2160 * Use assertThat(...).actual() style assertions in UpdateJakartaFacesApiTest
1 parent ed7df0d commit 2c285d5

3 files changed

Lines changed: 185 additions & 0 deletions

File tree

src/main/resources/META-INF/rewrite/jakarta-faces-3.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ recipeList:
5858
groupId: jakarta.faces
5959
artifactId: jakarta.faces-api
6060
newVersion: 3.0.x
61+
- org.openrewrite.java.dependencies.ChangeDependency:
62+
oldGroupId: com.sun.faces
63+
oldArtifactId: jsf-api
64+
newGroupId: jakarta.faces
65+
newArtifactId: jakarta.faces-api
66+
newVersion: 3.0.x
67+
- org.openrewrite.java.dependencies.ChangeDependency:
68+
oldGroupId: com.sun.faces
69+
oldArtifactId: jsf-impl
70+
newGroupId: org.glassfish
71+
newArtifactId: jakarta.faces
72+
newVersion: 3.0.x
73+
- org.openrewrite.java.dependencies.ChangeDependency:
74+
oldGroupId: org.glassfish
75+
oldArtifactId: javax.faces
76+
newGroupId: org.glassfish
77+
newArtifactId: jakarta.faces
78+
newVersion: 3.0.x
6179
- org.openrewrite.java.ChangePackage:
6280
oldPackageName: javax.faces
6381
newPackageName: jakarta.faces

src/main/resources/META-INF/rewrite/jakarta-faces-4.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ recipeList:
4848
groupId: jakarta.faces
4949
artifactId: jakarta.faces-api
5050
newVersion: 4.0.x
51+
- org.openrewrite.java.dependencies.UpgradeDependencyVersion:
52+
groupId: org.glassfish
53+
artifactId: jakarta.faces
54+
newVersion: 4.0.x
5155
---
5256
type: specs.openrewrite.org/v1beta/recipe
5357
name: org.openrewrite.java.migrate.jakarta.JakartaFacesXhtmlEE10
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
* <p>
4+
* Licensed under the Moderne Source Available License (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://docs.moderne.io/licensing/moderne-source-available-license
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.openrewrite.java.migrate.jakarta;
17+
18+
import org.junit.jupiter.api.Nested;
19+
import org.junit.jupiter.api.Test;
20+
import org.openrewrite.DocumentExample;
21+
import org.openrewrite.test.RecipeSpec;
22+
import org.openrewrite.test.RewriteTest;
23+
24+
import static org.assertj.core.api.Assertions.assertThat;
25+
import static org.openrewrite.maven.Assertions.pomXml;
26+
27+
class UpdateJakartaFacesApiTest {
28+
29+
@Nested
30+
class Faces3 implements RewriteTest {
31+
@Override
32+
public void defaults(RecipeSpec spec) {
33+
spec.recipeFromResources("org.openrewrite.java.migrate.jakarta.UpdateJakartaFacesApi3");
34+
}
35+
36+
@DocumentExample
37+
@Test
38+
void migrateSunFacesJsfApi() {
39+
rewriteRun(
40+
//language=xml
41+
pomXml(
42+
"""
43+
<project>
44+
<groupId>com.example</groupId>
45+
<artifactId>jsf-app</artifactId>
46+
<version>1.0.0</version>
47+
<dependencies>
48+
<dependency>
49+
<groupId>com.sun.faces</groupId>
50+
<artifactId>jsf-api</artifactId>
51+
<version>2.2.20</version>
52+
</dependency>
53+
</dependencies>
54+
</project>
55+
""",
56+
spec -> spec.after(pom -> assertThat(pom)
57+
.contains("<groupId>jakarta.faces</groupId>")
58+
.contains("<artifactId>jakarta.faces-api</artifactId>")
59+
.containsPattern("<version>3\\.0\\.\\d+</version>")
60+
.doesNotContain("<groupId>com.sun.faces</groupId>")
61+
.doesNotContain("<artifactId>jsf-api</artifactId>")
62+
.actual())
63+
)
64+
);
65+
}
66+
67+
@Test
68+
void migrateSunFacesJsfImpl() {
69+
rewriteRun(
70+
//language=xml
71+
pomXml(
72+
"""
73+
<project>
74+
<groupId>com.example</groupId>
75+
<artifactId>jsf-app</artifactId>
76+
<version>1.0.0</version>
77+
<dependencies>
78+
<dependency>
79+
<groupId>com.sun.faces</groupId>
80+
<artifactId>jsf-impl</artifactId>
81+
<version>2.2.20</version>
82+
</dependency>
83+
</dependencies>
84+
</project>
85+
""",
86+
spec -> spec.after(pom -> assertThat(pom)
87+
.contains("<groupId>org.glassfish</groupId>")
88+
.contains("<artifactId>jakarta.faces</artifactId>")
89+
.containsPattern("<version>3\\.0\\.\\d+</version>")
90+
.doesNotContain("<groupId>com.sun.faces</groupId>")
91+
.doesNotContain("<artifactId>jsf-impl</artifactId>")
92+
.actual())
93+
)
94+
);
95+
}
96+
97+
@Test
98+
void migrateGlassfishJavaxFaces() {
99+
rewriteRun(
100+
//language=xml
101+
pomXml(
102+
"""
103+
<project>
104+
<groupId>com.example</groupId>
105+
<artifactId>jsf-app</artifactId>
106+
<version>1.0.0</version>
107+
<dependencies>
108+
<dependency>
109+
<groupId>org.glassfish</groupId>
110+
<artifactId>javax.faces</artifactId>
111+
<version>2.3.9</version>
112+
</dependency>
113+
</dependencies>
114+
</project>
115+
""",
116+
spec -> spec.after(pom -> assertThat(pom)
117+
.contains("<groupId>org.glassfish</groupId>")
118+
.contains("<artifactId>jakarta.faces</artifactId>")
119+
.containsPattern("<version>3\\.0\\.\\d+</version>")
120+
.doesNotContain("<artifactId>javax.faces</artifactId>")
121+
.actual())
122+
)
123+
);
124+
}
125+
}
126+
127+
@Nested
128+
class Faces4 implements RewriteTest {
129+
@Override
130+
public void defaults(RecipeSpec spec) {
131+
spec.recipeFromResources("org.openrewrite.java.migrate.jakarta.UpdateJakartaFacesApi4");
132+
}
133+
134+
@Test
135+
void upgradeGlassfishJakartaFaces() {
136+
rewriteRun(
137+
//language=xml
138+
pomXml(
139+
"""
140+
<project>
141+
<groupId>com.example</groupId>
142+
<artifactId>jsf-app</artifactId>
143+
<version>1.0.0</version>
144+
<dependencies>
145+
<dependency>
146+
<groupId>org.glassfish</groupId>
147+
<artifactId>jakarta.faces</artifactId>
148+
<version>3.0.3</version>
149+
</dependency>
150+
</dependencies>
151+
</project>
152+
""",
153+
spec -> spec.after(pom -> assertThat(pom)
154+
.contains("<groupId>org.glassfish</groupId>")
155+
.contains("<artifactId>jakarta.faces</artifactId>")
156+
.containsPattern("<version>4\\.0\\.\\d+</version>")
157+
.doesNotContain("<version>3.0.3</version>")
158+
.actual())
159+
)
160+
);
161+
}
162+
}
163+
}

0 commit comments

Comments
 (0)