diff --git a/appserver/tests/payara-samples/samples/pom.xml b/appserver/tests/payara-samples/samples/pom.xml
index 252c574b6a7..1548bf04cf8 100644
--- a/appserver/tests/payara-samples/samples/pom.xml
+++ b/appserver/tests/payara-samples/samples/pom.xml
@@ -2,7 +2,7 @@
+
+ 4.0.0
+
+
+ fish.payara.samples
+ payara-samples-profiled-tests
+ 6.2023.10-SNAPSHOT
+
+
+ use-bundled-jsf-primefaces
+ Payara Samples - Payara - Use Bundled JSF with PrimeFaces
+ war
+
+
+
+ jakarta.platform
+ jakarta.jakartaee-api
+ provided
+
+
+
+
+
+ org.glassfish
+ jakarta.faces
+ 4.0.4
+
+
+
+ org.primefaces
+ primefaces
+ 13.0.1
+ jakarta
+
+
+
+ org.jboss.shrinkwrap.resolver
+ shrinkwrap-resolver-impl-maven
+ test
+
+
+ org.jboss.shrinkwrap.resolver
+ shrinkwrap-resolver-api-maven
+ test
+
+
+
+ fish.payara.samples
+ samples-test-utils
+
+
+
+ org.glassfish.jersey.core
+ jersey-client
+ test
+
+
+ org.glassfish.jersey.inject
+ jersey-hk2
+ test
+
+
+
+
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/java/fish/payara/samples/usebundledjsf/primefaces/JSFVersion.java b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/java/fish/payara/samples/usebundledjsf/primefaces/JSFVersion.java
new file mode 100644
index 00000000000..78ec7bf7b5b
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/java/fish/payara/samples/usebundledjsf/primefaces/JSFVersion.java
@@ -0,0 +1,55 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2023 Payara Foundation and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://github.com/payara/Payara/blob/master/LICENSE.txt
+ * See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * The Payara Foundation designates this particular file as subject to the "Classpath"
+ * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package fish.payara.samples.usebundledjsf.primefaces;
+
+import jakarta.enterprise.context.RequestScoped;
+import jakarta.faces.context.FacesContext;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+
+@RequestScoped
+@Path("/jsf")
+public class JSFVersion {
+
+ @GET
+ public String getVersion() {
+ return FacesContext.class.getPackage().getImplementationVersion();
+ }
+}
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/java/fish/payara/samples/usebundledjsf/primefaces/Resources.java b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/java/fish/payara/samples/usebundledjsf/primefaces/Resources.java
new file mode 100644
index 00000000000..b749c19bd45
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/java/fish/payara/samples/usebundledjsf/primefaces/Resources.java
@@ -0,0 +1,47 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2023 Payara Foundation and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://github.com/payara/Payara/blob/master/LICENSE.txt
+ * See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * The Payara Foundation designates this particular file as subject to the "Classpath"
+ * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package fish.payara.samples.usebundledjsf.primefaces;
+
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.core.Application;
+
+@ApplicationPath("/resources")
+public class Resources extends Application {
+}
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/beans.xml b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 00000000000..0695ad686e5
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1,46 @@
+
+
+
+
\ No newline at end of file
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/faces-config.xml b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/faces-config.xml
new file mode 100644
index 00000000000..dfaffa331a6
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/faces-config.xml
@@ -0,0 +1,45 @@
+
+
+
+
\ No newline at end of file
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/payara-web.xml b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/payara-web.xml
new file mode 100644
index 00000000000..dadd42cc1b0
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/payara-web.xml
@@ -0,0 +1,47 @@
+
+
+
+
+ usebundledjsfsample
+
+
+
\ No newline at end of file
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/web.xml b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..bf5dc95113e
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,197 @@
+
+
+
+
+
+ 30
+
+
+
+ fish.payara.faces.enableParallelInit
+ true
+
+
+
+ com.sun.faces.enableThreading
+ true
+
+
+
+ primefaces.THEME
+ bootstrap
+
+
+
+ primefaces.MOVE_SCRIPTS_TO_BOTTOM
+ true
+
+
+
+ primefaces.FONT_AWESOME
+ true
+
+
+
+ primefaces.CLIENT_SIDE_VALIDATION
+ true
+
+
+
+ jakarta.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL
+ true
+
+
+
+ jakarta.faces.VALIDATE_EMPTY_FIELDS
+ true
+
+
+
+ jakarta.faces.ENABLE_CDI_RESOLVER_CHAIN
+ true
+
+
+
+ jakarta.faces.validator.ENABLE_VALIDATE_WHOLE_BEAN
+ true
+
+
+
+ com.sun.faces.enableMissingResourceLibraryDetection
+ true
+
+
+
+ jakarta.faces.FACELETS_BUFFER_SIZE
+ 262144
+
+
+
+
+ jakarta.faces.FACELETS_REFRESH_PERIOD
+
+ 1
+
+
+
+
+ jakarta.faces.PARTIAL_STATE_SAVING
+ true
+
+
+
+ jakarta.faces.PROJECT_STAGE
+ Development
+
+
+
+
+ State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2
+ jakarta.faces.STATE_SAVING_METHOD
+ server
+
+
+
+ jakarta.faces.FACELETS_SKIP_COMMENTS
+ true
+
+
+
+ jakarta.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE
+ true
+
+
+
+
+
+ com.sun.faces.numberOfViewsInSession
+ 15
+
+
+
+
+ com.sun.faces.compressViewState
+ false
+
+
+
+
+ woff
+ application/x-font-woff
+
+
+
+ woff2
+ application/x-font-woff2
+
+
+
+ ttf
+ application/x-font-ttf
+
+
+
+ eot
+ application/x-font-eot
+
+
+
+ svg
+ image/svg+xml
+
+
+
+
+ Faces Servlet
+ jakarta.faces.webapp.FacesServlet
+ 1
+
+
+ Faces Servlet
+ *.xhtml
+
+
+ index.xhtml
+
+
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/index.xhtml b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/index.xhtml
new file mode 100644
index 00000000000..b64e7beeeac
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/main/webapp/index.xhtml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/DontUseBundledJsfTest.java b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/DontUseBundledJsfTest.java
new file mode 100644
index 00000000000..77cc945fe82
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/DontUseBundledJsfTest.java
@@ -0,0 +1,99 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2023 Payara Foundation and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://github.com/payara/Payara/blob/master/LICENSE.txt
+ * See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * The Payara Foundation designates this particular file as subject to the "Classpath"
+ * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package fish.payara.samples.usebundledjsf.primefaces;
+
+import fish.payara.samples.Libraries;
+import fish.payara.samples.PayaraArquillianTestRunner;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
+import java.io.File;
+import java.net.URI;
+
+/**
+ * Test to check that when an application bundles a JSF implementation in with itself, it needs to set 'useBundledJsf'
+ * to true and tell the class loader to not delegate to its parent.
+ */
+@RunWith(PayaraArquillianTestRunner.class)
+public class DontUseBundledJsfTest {
+
+ private final static String JSF_VERSION = "4.0.4";
+
+ @ArquillianResource
+ private URI uri;
+
+ @Deployment
+ public static WebArchive createDeployment() {
+ return ShrinkWrap.create(WebArchive.class, "dontusebundledjsfprimefaces.war")
+ .addClasses(Resources.class, JSFVersion.class)
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "beans.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "faces-config.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "web.xml"))
+ // Don't add payara-web.xml so that useBundledJsf and class loader delegation are not configured
+ // .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "payara-web.xml"))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.glassfish:jakarta.faces:" + JSF_VERSION))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.primefaces:primefaces:13.0.1-jakarta"))
+ ;
+ }
+
+ @Test
+ @RunAsClient
+ public void checkFacesContextImplementationVersion() {
+ WebTarget target = ClientBuilder.newClient().target(uri).path("resources").path("jsf");
+ Response response = target.request().get();
+
+ String message = response.readEntity(String.class);
+
+ System.out.println("FacesContext implementation version is: " + message);
+
+ Assert.assertEquals(200, response.getStatus());
+ // Check that we're NOT using the bundled JSF version
+ Assert.assertNotEquals(JSF_VERSION, message);
+ }
+}
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/ParallelUseBundledJsfTest.java b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/ParallelUseBundledJsfTest.java
new file mode 100644
index 00000000000..f6218af7f01
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/ParallelUseBundledJsfTest.java
@@ -0,0 +1,126 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2023 Payara Foundation and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://github.com/payara/Payara/blob/master/LICENSE.txt
+ * See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * The Payara Foundation designates this particular file as subject to the "Classpath"
+ * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package fish.payara.samples.usebundledjsf.primefaces;
+
+import fish.payara.samples.Libraries;
+import fish.payara.samples.PayaraArquillianTestRunner;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.OperateOnDeployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
+import java.io.File;
+import java.net.URI;
+
+@RunWith(PayaraArquillianTestRunner.class)
+public class ParallelUseBundledJsfTest {
+
+ private final static String JSF_VERSION = "4.0.4";
+
+ @ArquillianResource
+ private URI uri;
+
+ @Deployment(name = "dontusebundledjsfprimefaces")
+ public static WebArchive createDontDeployment() {
+ return ShrinkWrap.create(WebArchive.class, "dontusebundledjsfprimefaces.war")
+ .addClasses(Resources.class, JSFVersion.class)
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "beans.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "faces-config.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "web.xml"))
+ // Don't add payara-web.xml so that useBundledJsf and class loader delegation are not configured
+ // .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "payara-web.xml"))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.glassfish:jakarta.faces:" + JSF_VERSION))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.primefaces:primefaces:13.0.1-jakarta"))
+ ;
+ }
+
+ @Deployment(name = "usebundledjsfprimefaces")
+ public static WebArchive createUseDeployment() {
+ return ShrinkWrap.create(WebArchive.class, "usebundledjsfprimefaces.war")
+ .addClasses(Resources.class, JSFVersion.class)
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "beans.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "faces-config.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "web.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "payara-web.xml"))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.glassfish:jakarta.faces:" + JSF_VERSION))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.primefaces:primefaces:13.0.1-jakarta"))
+ ;
+ }
+
+
+
+ @Test
+ @RunAsClient
+ @OperateOnDeployment("dontusebundledjsfprimefaces")
+ public void checkDontFacesContextImplementationVersion() {
+ WebTarget target = ClientBuilder.newClient().target(uri).path("resources").path("jsf");
+ Response response = target.request().get();
+
+ String message = response.readEntity(String.class);
+
+ System.out.println("FacesContext implementation version is: " + message);
+
+ Assert.assertEquals(200, response.getStatus());
+ Assert.assertNotEquals(JSF_VERSION, message);
+ }
+
+ @Test
+ @RunAsClient
+ @OperateOnDeployment("usebundledjsfprimefaces")
+ public void checkUseFacesContextImplementationVersion() {
+ WebTarget target = ClientBuilder.newClient().target(uri).path("resources").path("jsf");
+ Response response = target.request().get();
+
+ String message = response.readEntity(String.class);
+
+ System.out.println("FacesContext implementation version is: " + message);
+
+ Assert.assertEquals(200, response.getStatus());
+ Assert.assertEquals(JSF_VERSION, message);
+ }
+}
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/UseBundledJsfEarTest.java b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/UseBundledJsfEarTest.java
new file mode 100644
index 00000000000..8f32d69c50c
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/UseBundledJsfEarTest.java
@@ -0,0 +1,101 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2023 Payara Foundation and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://github.com/payara/Payara/blob/master/LICENSE.txt
+ * See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * The Payara Foundation designates this particular file as subject to the "Classpath"
+ * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package fish.payara.samples.usebundledjsf.primefaces;
+
+import fish.payara.samples.Libraries;
+import fish.payara.samples.NotMicroCompatible;
+import fish.payara.samples.PayaraArquillianTestRunner;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
+import java.io.File;
+import java.net.URI;
+
+/**
+ * Test that checks that a WAR embedded within an EAR can still use its bundled JSF implementation.
+ * Bundling the JSF implementation within the EAR and expecting the WAR to be able to access it is out of scope.
+ */
+@RunWith(PayaraArquillianTestRunner.class)
+@NotMicroCompatible
+public class UseBundledJsfEarTest {
+
+ private final static String JSF_VERSION = "4.0.4";
+
+ @ArquillianResource
+ private URI uri;
+
+ @Deployment
+ public static EnterpriseArchive createDeployment() {
+ return ShrinkWrap.create(EnterpriseArchive.class, "usebundledjsfprimefacesear.ear")
+ .addAsModule(ShrinkWrap.create(WebArchive.class, "usebundledjsfprimefaces.war")
+ .addClasses(Resources.class, JSFVersion.class)
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "beans.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "faces-config.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "web.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "payara-web.xml"))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.glassfish:jakarta.faces:" + JSF_VERSION))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.primefaces:primefaces:13.0.1-jakarta"))
+ );
+ }
+
+ @Test
+ @RunAsClient
+ public void checkFacesContextImplementationVersion() {
+ WebTarget target = ClientBuilder.newClient().target(uri).path("resources").path("jsf");
+ Response response = target.request().get();
+
+ String message = response.readEntity(String.class);
+
+ System.out.println("FacesContext implementation version is: " + message);
+
+ Assert.assertEquals(200, response.getStatus());
+ Assert.assertEquals(JSF_VERSION, message);
+ }
+}
\ No newline at end of file
diff --git a/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/UseBundledJsfTest.java b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/UseBundledJsfTest.java
new file mode 100644
index 00000000000..660d11af721
--- /dev/null
+++ b/appserver/tests/payara-samples/samples/use-bundled-jsf-primefaces/src/test/java/fish/payara/samples/usebundledjsf/primefaces/UseBundledJsfTest.java
@@ -0,0 +1,97 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2023 Payara Foundation and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://github.com/payara/Payara/blob/master/LICENSE.txt
+ * See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * The Payara Foundation designates this particular file as subject to the "Classpath"
+ * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package fish.payara.samples.usebundledjsf.primefaces;
+
+import fish.payara.samples.Libraries;
+import fish.payara.samples.PayaraArquillianTestRunner;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
+import java.io.File;
+import java.net.URI;
+
+/**
+ * Test to check that its possible to override the Server's JSF implementation with one bundled within the application
+ * when using PrimeFaces.
+ */
+@RunWith(PayaraArquillianTestRunner.class)
+public class UseBundledJsfTest {
+
+ private final static String JSF_VERSION = "4.0.4";
+
+ @ArquillianResource
+ private URI uri;
+
+ @Deployment
+ public static WebArchive createDeployment() {
+ return ShrinkWrap.create(WebArchive.class, "usebundledjsfprimefaces.war")
+ .addClasses(Resources.class, JSFVersion.class)
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "beans.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "faces-config.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "web.xml"))
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF", "payara-web.xml"))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.glassfish:jakarta.faces:" + JSF_VERSION))
+ .addAsLibraries(Libraries.resolveMavenCoordinatesToFiles("org.primefaces:primefaces:13.0.1-jakarta"))
+ ;
+ }
+
+ @Test
+ @RunAsClient
+ public void checkFacesContextImplementationVersion() {
+ WebTarget target = ClientBuilder.newClient().target(uri).path("resources").path("jsf");
+ Response response = target.request().get();
+
+ String message = response.readEntity(String.class);
+
+ System.out.println("FacesContext implementation version is: " + message);
+
+ Assert.assertEquals(200, response.getStatus());
+ Assert.assertEquals(JSF_VERSION, message);
+ }
+}
\ No newline at end of file
diff --git a/appserver/web/war-util/src/main/java/org/glassfish/web/loader/WebappClassLoader.java b/appserver/web/war-util/src/main/java/org/glassfish/web/loader/WebappClassLoader.java
index b8beb93b8ae..f053eb33e08 100644
--- a/appserver/web/war-util/src/main/java/org/glassfish/web/loader/WebappClassLoader.java
+++ b/appserver/web/war-util/src/main/java/org/glassfish/web/loader/WebappClassLoader.java
@@ -1829,6 +1829,11 @@ protected synchronized Class> loadClass(String name, boolean resolve)
// Ignore
}
+ // If we haven't found it locally, and we're using bundled JSF, DON'T delegate any lookup if it's a JSF class
+ if (useMyFaces && !delegateLoad && (name.startsWith("javax.faces") || name.startsWith("jakarta.faces") || name.startsWith("com.sun.faces"))) {
+ throw new ClassNotFoundException(String.format("Class [%s] could not be found in bundled JSF", name));
+ }
+
// (3) Delegate if class was not found locally
if ((application.isWhitelistEnabled()? isWhitelisted : true) && !delegateLoad) {
if (logger.isLoggable(Level.FINER)) {