zoran jeremic
zoran jeremic

Reputation: 2138

CSS and Javascript loads too long on Tomcat 8 or 9

I have JSF application and it works fine when I run it on embedded Jetty server. However, when I deploy it to Tomcat 8.0.35 loading of the CSS and Javascript files takes more than 20 seconds. I have the same problem on the Tomcat running on Amazon AWS server and on the Tomcat running on local machine. These are all small files and none of them is loaded longer than 35ms on Jetty server.

Tomcat logs do not indicate any kind of problems with the application, and this is happening on every page, even on the login page.

The same problem I have with Tomcat 8 and Tomcat 9, but not with Tomcat 7.

I would appreciate if somebody could give me idea what should I check or how to search for the source of the problem.

Edit: This is a h:head section of login page, but same problem is everywhere else:

<h:head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://use.typekit.net/zvv0dgl.js"></script>
<script>try{Typekit.load({ async: true });}catch(e){}</script>
<title>ProSolo - Sign in</title>
<link href="#{request.contextPath}/resources/css2/bootstrap.min.css" rel="stylesheet" />
<link href="#{request.contextPath}/resources/css2/awesome-bootstrap-checkbox.css" rel="stylesheet" />
<link href="#{request.contextPath}/resources/css2/style.css" rel="stylesheet" />

Edit 2 (web.xml):

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:web="http://java.sun.com/xml/ns/javaee"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     metadata-complete="true" version="3.0">
    <display-name>ProSolo</display-name>
    <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <servlet>
    <servlet-name>fileServlet</servlet-name>
    <servlet-class>org.prosolo.services.upload.FileServlet</servlet-class>
    <init-param>
        <param-name>basePath</param-name>
        <param-value>/WEB-INF/resources</param-value>
    </init-param>
    </servlet>
    <servlet-mapping>
    <servlet-name>fileServlet</servlet-name>
    <url-pattern>/files/*</url-pattern>
    </servlet-mapping>
    <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
    <filter-name>opensessioninview</filter-name>
    <filter-class>org.prosolo.core.spring.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>singleSession</param-name>
        <param-value>true</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>opensessioninview</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
    <filter-name>Login Partial Response Redirect</filter-name>
    <filter-class>org.prosolo.core.jsf.LoginPartialResponseRedirectFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>Login Partial Response Redirect</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    <!--  
    <filter>
      <filter-name>PrimeFaces FileUpload Filter</filter-name>
      <filter-class>org.prosolo.core.jsf.primefaces.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>PrimeFaces FileUpload Filter</filter-name>
      <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    -->
    <filter>
    <filter-name>gzipResponseFilter</filter-name>
    <filter-class>org.omnifaces.filter.GzipResponseFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>gzipResponseFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        org.prosolo.core.spring.SpringConfig,
        org.prosolo.core.spring.security.SpringSecurityConfig,
        org.prosolo.core.hibernate.HibernateConfig
    </param-value>
    </context-param>
    <context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <context-param>
    <param-name>com.sun.faces.expressionFactory</param-name>
    <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
    </context-param>
    <!-- added for p:fileUpload, options: auto, native, commons-->
    <context-param>
    <param-name>primefaces.UPLOADER</param-name>
    <param-value>native</param-value>
    </context-param>
    <listener>
    <listener-class>org.prosolo.app.BeforeContextLoader</listener-class>
    </listener>
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <listener>
    <listener-class>org.prosolo.app.AfterContextLoader</listener-class>
    </listener>
    <listener>
    <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
    </listener>
    <listener>
    <listener-class>org.prosolo.web.SessionCountListener</listener-class>
    </listener>
    <error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/login.xhtml</location>
    </error-page>
    <error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/login.xhtml</location>
    </error-page>
    <session-config>
    <session-timeout>10</session-timeout>
    </session-config>
    <!-- In Production change javax.faces.FACELETS_REFRESH_PERIOD to -1 and javax.faces.PROJECT_STAGE to 'Production' -->
    <!-- In Development change javax.faces.FACELETS_REFRESH_PERIOD to 1 and javax.faces.PROJECT_STAGE to 'Development' -->
    <context-param>
    <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
    <param-value>-1</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Production</param-value>
    </context-param>
    <context-param>
    <param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
    <param-value>true</param-value>
    </context-param>
    <context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
    <param-value>true</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/functions.taglib.xml</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.el.parser.SKIP_IDENTIFIER_CHECK</param-name>
    <param-value>true</param-value>
    </context-param>
    <context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>none</param-value>
    </context-param>
    <context-param>
    <param-name>primefaces.PUBLIC_CAPTCHA_KEY</param-name>
    <param-value>***************************</param-value>
    </context-param>
    <context-param>
    <param-name>primefaces.PRIVATE_CAPTCHA_KEY</param-name>
    <param-value>********************************</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
    <param-value>20</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
    <param-value>false</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>
    <param-value>false</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.annotation.SCAN_PACKAGES</param-name>
    <param-value>org.prosolo.web</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME</param-name>
    <param-value>true</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.USE_ENCRYPTION</param-name>
    <param-value>false</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.ALGORITHM</param-name>
    <param-value>AES</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.SECRET</param-name>
    <param-value>Q0hBTkdFIFNFQ1JFVCEhIQ==</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.MAC_SECRET</param-name>
    <param-value>Q0hBTkdFIE1BQ1NFQ1JFVA==</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.RESOURCE_EXCLUDES</param-name>
    <param-value>.class .jsp .jspx .properties .xhtml .xml</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
    <param-value>165535</param-value>
    </context-param>

    <listener>
    <listener-class>org.ocpsoft.rewrite.servlet.impl.RewriteServletRequestListener</listener-class>
    </listener>

    <listener>
    <listener-class>org.ocpsoft.rewrite.servlet.impl.RewriteServletContextListener</listener-class>
    </listener>

    <filter>
    <filter-name>OCPsoft Rewrite Filter</filter-name>
    <filter-class>org.ocpsoft.rewrite.servlet.RewriteFilter</filter-class>
    <async-supported>true</async-supported>
    </filter>
    <filter-mapping>
    <filter-name>OCPsoft Rewrite Filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    <!-- <filter>
     <filter-name>Save Page Url In Session Filter</filter-name>
     <filter-class>org.prosolo.core.jsf.SavePageUrlInSessionFilter</filter-class>
   </filter>
   <filter-mapping>
     <filter-name>Save Page Url In Session Filter</filter-name>
     <url-pattern>/*</url-pattern>
     <dispatcher>FORWARD</dispatcher>
     <dispatcher>REQUEST</dispatcher>
   </filter-mapping> -->
</web-app>

Upvotes: 1

Views: 1953

Answers (1)

Jalal Kiswani
Jalal Kiswani

Reputation: 765

I would recommand direct link to CSS files and java script using <script> and <link> , and to overcome the issue of relative path , prefix the url with #{request.contextPath}, for example , to reference resources/css/app.css , use: <link href="#{request.contextPath}/resources/css/app.css" rel="stylesheet" />

For more information , check my article "Java Server Faces in Real-Life Applications" at dzone .

Upvotes: 1

Related Questions