0

I am currently trying to move a java EE 8 project running on wildfly to the latest spring boot.

For this i will need primefaces, primefaces-extensions and omnifaces cause of it's components i am already using and also designed (buyed) theme.

Starting with the latest spring boot in combination with joinfaces i currently try to define the welcome page or redirect to the index.xhtml page but anything i tried failed.

Here is my current sources:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<!-- Project settings -->
<groupId>com.skf.ecocalcweb</groupId>
<artifactId>EcoCalcDD4Web</artifactId>
<version>2.0.0</version>
<packaging>jar</packaging>

<!-- Using spring boot as parent -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<!-- Project properties -->
<properties>
    <!-- General settings -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <java.version>1.8</java.version>
    <!-- Libraries versions -->
    <lombok.version>1.18.12</lombok.version>
    <joinfaces.version>4.1.4</joinfaces.version>
    <primefaces.core.version>7.0.11</primefaces.core.version>
    <primefaces.extensions.version>7.0.3</primefaces.extensions.version>
    <omnifaces.version>3.4.1</omnifaces.version>
    <fontawesome.version>5.12.0</fontawesome.version>
</properties>

<!-- Use joinfaces for jsf starters -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.joinfaces</groupId>
            <artifactId>joinfaces-dependencies</artifactId>
            <version>${joinfaces.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<!-- JAR-Dependencies -->
<dependencies>
    <!-- Spring boot starters -->
    <!-- Exclude mojarra, so use myfaces instead -->
    <dependency>
        <groupId>org.joinfaces</groupId>
        <artifactId>primefaces-spring-boot-starter</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.joinfaces</groupId>
                <artifactId>mojarra-spring-boot-starter</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.joinfaces</groupId>
        <artifactId>myfaces-spring-boot-starter</artifactId>
    </dependency>
    <!-- Also use omnifaces3, so latest jsf version must be used -->
    <dependency>
        <groupId>org.joinfaces</groupId>
        <artifactId>omnifaces3-spring-boot-starter</artifactId>
    </dependency>
    <!-- Java Enterprise API for using primefaces in JSF -->
    <dependency>
        <groupId>javax.enterprise</groupId>
        <artifactId>cdi-api</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <!-- OmniFaces -->
    <dependency>
        <groupId>org.omnifaces</groupId>
        <artifactId>omnifaces</artifactId>
        <version>${omnifaces.version}</version>
    </dependency>
    <!-- Primefaces core -->
    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>${primefaces.core.version}-SNAPSHOT</version>
    </dependency>
    <!-- Primefaces extensions -->
    <dependency>
        <groupId>org.primefaces.extensions</groupId>
        <artifactId>primefaces-extensions</artifactId>
        <version>${primefaces.extensions.version}</version>
    </dependency>
    <!-- Primefaces theme -->
    <dependency>
        <groupId>com.skf.ecocalcweb</groupId>
        <artifactId>PrimefacesTheme</artifactId>
        <version>1.0.0</version>
    </dependency>
    <!-- Font Awesome -->
    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>font-awesome</artifactId>
        <version>${fontawesome.version}</version>
    </dependency>
    <!-- Lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

<!-- Package as an executable jar -->
<build>
    <!-- Final name of war-file -->
    <finalName>${project.artifactId}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

/src/main/java/com/test/Application.java

    @SpringBootApplication
public class Application {

  public static void main(String[] args) {
    SpringApplication app = new SpringApplication(Application.class);
    app.run(args);
  }

  @Bean
  public ServletRegistrationBean facesServletRegistration() {
    FacesServlet servlet = new FacesServlet();
    ServletRegistrationBean registration = new ServletRegistrationBean(servlet, new String[]{"*.xhtml"});
    registration.setName("Faces Servlet");
    registration.setLoadOnStartup(1);
    registration.setEnabled(true);
    registration.setOrder(1);
    return registration;
  }

  @Bean
  public ServletContextInitializer servletContextInitializer() {
    return servletContext -> {
      // MyFaces
      servletContext.setInitParameter("org.apache.myfaces.LOG_WEB_CONTEXT_PARAMS", Boolean.FALSE.toString());
      // Primefaces
      servletContext.setInitParameter("primefaces.THEME", "harmony-fate");
      servletContext.setInitParameter("primefaces.MOVE_SCRIPTS_TO_BOTTOM", Boolean.FALSE.toString());
      servletContext.setInitParameter("primefaces.FONT_AWESOME", Boolean.TRUE.toString());
      // Omnifaces
      servletContext.setInitParameter("org.omnifaces.SOCKET_ENDPOINT_ENABLED", Boolean.TRUE.toString());
      // JavaX
      servletContext.setInitParameter("javax.faces.PROJECT_STAGE", "Production");
      servletContext.setInitParameter("javax.faces.DEFAULT_SUFFIX", ".xhtml");
      servletContext.setInitParameter("com.sun.faces.enableRestoreView11Compatibility", Boolean.TRUE.toString());
      servletContext.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", Boolean.TRUE.toString());
      servletContext.setInitParameter("javax.faces.STATE_SAVING_METHOD", "server");
      servletContext.setInitParameter("com.sun.faces.compressViewState", Boolean.FALSE.toString());
      servletContext.setInitParameter("com.sun.face.serializeServerState", Boolean.FALSE.toString());
      servletContext.setInitParameter("javax.faces.FACELETS_REFRESH_PERIOD", "-1");
      servletContext.setInitParameter("javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL", Boolean.TRUE.toString());
      servletContext.setInitParameter("javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE", Boolean.TRUE.toString());
      servletContext.setInitParameter("javax.faces.ENABLE_CDI_RESOLVER_CHAIN", Boolean.TRUE.toString());
    };
  }
}

/src/main/java/com/test/controllers/Index.java

@Getter
@Setter
@RequestScope
@Named
public class Index {

  private String firstName = "John";
  private String lastName = "Doe";

  public String showGreeting() {
    return "Hello " + firstName + " " + lastName + "!";
  }
}

/src/main/resources/META-INF/resources/index.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.org/ui">

<h:head>
  <title>PrimeFaces Hello World Example</title>
</h:head>

<h:body>
  <h:form id="helloworld-form">

    <p:panel header="PrimeFaces Hello World Example">
      <h:panelGrid columns="2" cellpadding="4">
        <h:outputText value="First Name: " />
        <p:inputText id="first-name" value="#{index.firstName}" />

        <h:outputText value="Last Name: " />
        <p:inputText id="last-name" value="#{index.lastName}" />

        <p:commandButton id="submit" value="Submit"
          update="greeting-panel"
          oncomplete="PF('greetingDialog').show()" />
      </h:panelGrid>
    </p:panel>

    <p:dialog header="Greeting" widgetVar="greetingDialog"
      modal="true" resizable="false">
      <h:panelGrid id="greeting-panel" columns="1" cellpadding="4">
        <h:outputText value="#{index.showGreeting()}" />
      </h:panelGrid>
    </p:dialog>

  </h:form>
</h:body>
</html>

/src/main/resources/META-INF/resources/application.properties

# the embedded application server config
server.port=80
server.servlet.context-path=/

# thymeleaf templating engine config
spring.thymeleaf.enabled=false

So what's needed here to set the welcome-page for a jsf application right ?

When i directly called http://localhost/index.xhtml the primefaces page will be rendered right, but when i enter http://localhost/ no redirect to the index.xhtml will be made and i currently found nothing which is working as a "redirect" ...

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
joy77
  • 51
  • 2
  • Are you using JoinFaces? You have it in your label but if you were using it this would all work, – Melloware Feb 19 '20 at 14:47
  • And if you create a plain jsf page (non-primefaces) it does work? Your title suggests it does. Or if you don;t use omnifaces it works (your tagging suggests it does – Kukeltje Feb 19 '20 at 14:58
  • off-topic: _"I am currently trying to move a java EE 8 project running on wildfly to the latest spring boot."_ Out of curiosity: why? – Kukeltje Feb 19 '20 at 15:19
  • @Melloware : Yes, i am using JoinFaces as you can see in the pom.xml which i posted here, but with the "latest" version i can not redirect to the welcome page. When i directly enter the url it works, but not when i only enter the url of the context-path ... – joy77 Feb 20 '20 at 06:51
  • @Kukeltje : My problem here is not that primefaces or omnifaces is not working, but i don't know how to redirect to index.xhtml as welcome-page. When i only enter the context-path like "http://localhost/" i will get the error page 404 instead of redirecting the user to "http://localhost/index.xhtml", thats currently my problem. Could it be that the latest version that i used is buggy ? joinfaces version 4.1.4 in combination with spring-boot-starter-parent 2.2.4 – joy77 Feb 20 '20 at 06:56
  • @Kukeltje : The reason why i won't to change is that i want split my big monolith app into small pieces for better maintainance and also performance reasons. I compared thorntail and spring-boot and in my case it seems that spring-boot is currently the better way. Also when i need to switch to Java 11 instead of Java 8. Also the thing that when i package the Spring Boot Application into a simple JAR-File without the need of any external configurated Application-Server like Wildfly/JBoss/Glassfish makes it easier for deploy a new app ... – joy77 Feb 20 '20 at 07:04
  • 1
    Some notes: 1. You don't need to specifiy the facesServletRegistration Bean. Joinfaces does that for you. 2. The properties you set in your servletContextInitializer Bean can be set using simple spring boot properties: https://docs.joinfaces.org/4.1.4/reference/#properties – larsgrefer Mar 02 '20 at 19:25

1 Answers1

2

I think i currently found the solution :
So i post it for all others which are start using spring boot and primefaces together:

Adding this dependency will fix my problem with the welcome page as xhtml :

<!-- Add spring boot web needed for navigation -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Then i can use the following class file to set my welcome-page:

/src/main/java/com/test/navigation/WelcomePageRedirect.java

@Configuration
public class WelcomePageRedirect implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/")
                .setViewName("forward:/index.xhtml");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }
}

Now the following technologies are working together:

  • Java 8 (And also Java 11 !)
  • Primefaces 7.0.11 + Primefaces Extensions
  • Omnifaces 3.4.1
  • Latest FontAwesome 5.12.0 in combination with Primefaces "old" FontAwesome
  • Spring Boot 2.2.4
  • JoinFaces 4.1.4
  • MyFaces 2.3
joy77
  • 51
  • 2