Thursday, October 25, 2012

Speedup jetty-maven-plugin startup time

  • Create a own profile - this allows more flexibility
  • <profile>
        <id>jetty-run</id>
    </profile>
    
  • Add jetty-maven-plugin to the profile. We also configure the plugin to get all resources from the src directory and only scan the java sources
  • <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <configuration>
            <webAppSourceDirectory>${basedir}/src/main/webapp</webAppSourceDirectory>
            <scanIntervalSeconds>2</scanIntervalSeconds>
            <scanTargets>
                <scanTarget>src/main/java</scanTarget>
            </scanTargets>
        </configuration>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>run</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    
  • Skip unit testing via profile property
  • <properties>
        <maven.test.skip>true</maven.test.skip>
    </properties>
    
  • Skip building the WAR file
  • <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <executions>
            <execution>
                <id>default-war</id>
                <phase>none</phase>
            </execution>
        </executions>
    </plugin>
    
  • If you optimize and aggregate your javascript or CSS files, skip this too! Compression of this files is on localhost just prevents debugging. We created an own servlet which merges the files on-the-fly. Changes on JS or CSS will be also available after F5 in your browser - that's the nice side effect of the servlet :)
    • Skip optimzation (we use the primefaces-extensions plugin for this)
    • <plugin>
          <groupId>org.primefaces.extensions</groupId>
          <artifactId>resources-optimizer-maven-plugin</artifactId>
          <executions>
              <execution>
                  <id>optimize</id>
                  <phase>none</phase>
              </execution>
          </executions>
      </plugin>
      
    • Create a servlet to merge the resources (we also implemented a init-param called includeDirectory to read all source files)
    • @Override
      protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
          throws ServletException, IOException
      {
          final OutputStream ouputStream = response.getOutputStream();
          response.setContentType(getServletConfig().getInitParameter("contentType");
      
          final List<File> filesToMerge = getFiles(getServletContext().getRealPath(getServletConfig().getInitParameter("includeDirectory")));
      
          for (final File fileToMerge : filesToMerge) {
          final FileInputStream inputStream = new FileInputStream(fileToMerge);
              IOUtils.copy(inputStream, ouputStream);
              inputStream.close();
          }
      
          ouputStream.close();
      }
      
      
    • For example, if your optimizer plugin aggregates your javascript files to "/javascript/bundle.js", we must overwrite this URL via a servlet mapping.
      We just create a second web.xml (this is just for localhost and jetty) with the name "web-localhost.xml" in your "src/main/webapp/WEB-INF" directory with the following servlet mapping
    • <servlet>
          <servlet-name>Merge Javascript Servlet</servlet-name>
          <servlet-class>xxx.servlet.MergeResourceServlet</servlet-class>
          <init-param>
              <param-name>includeDirectory</param-name>
              <param-value>/javascript/</param-value>
          </init-param>
          <init-param>
              <param-name>contentType</param-name>
              <param-value>application/x-javascript</param-value>
          </init-param>
      </servlet>
      <servlet-mapping>
          <servlet-name>Merge Javascript Servlet</servlet-name>
          <url-pattern>/javascript/bundle.js</url-pattern>
      </servlet-mapping>
      
    • Now we configure jetty to use our "web-localhost.xml" as overrideDescriptor
    • <plugin>
          <groupId>org.mortbay.jetty</groupId>
          <artifactId>jetty-maven-plugin</artifactId>
          <configuration>
              <webAppConfig>
                  <overrideDescriptor>src/main/webapp/WEB-INF/web-localhost.xml</overrideDescriptor>
              </webAppConfig>
              ...
          </configuration>
      </plugin>
Finished! You will be able to start jetty now via "mvn package -P jetty-run".

4 comments:

  1. HI Thomas,

    I read your article it was very informative.I have tried a web dynamic project in tomcat7 + jsf2+ Prime faces 3.4. It works well. But i could not start a same application in WAS8. Can u please guide in starting web dynamic project with prime faces 3.4+ jsf2 and not from maven.

    ReplyDelete
  2. Hi,

    sorry, i never used WAS but might it be possible that you ship the JSF jars in your WAR file? This is not required on a AS because they already has a JSF implementation.

    Sorry but i always maven :)

    ReplyDelete
  3. You're always mavening? What about debugging?

    As for the question (although the answer's probably very late): Try http://examples.javacodegeeks.com/enterprise-java/jsf-2-0-eclipse-ide-support/. And chances are http://www.beyondjava.net will dedicate an article to the topic soon :).

    ReplyDelete
  4. Debugging is quite easy via "mvnDebug" instead "mvn" ;)

    ReplyDelete