Moving Your Application to Production

Gerald Gierer

December 2013

(For more resources related to this topic, see here.)

We will start by examining the Sencha Cmd compiler.

Compiling with Sencha Cmd

This section will focus on using Sencha Cmd to compile our Ext JS 4 application for deployment within a Web Archive (WAR) file. The goal of the compilation process is to create a single JavaScript file that contains all of the code needed for the application, including all the Ext JS 4 dependencies.

The index.html file that was created during the application skeleton generation is structured as follows:

<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>TTT</title> <!-- <x-compile> --> <!-- <x-bootstrap> --> <link rel="stylesheet" href="bootstrap.css"> <script src = "ext/ext-dev.js"></script> <script src = "bootstrap.js"></script> <!-- </x-bootstrap> --> <script src = "app.js"></script> <!-- </x-compile> --> </head> <body></body> </html>

The open and close tags of the x-compile directive enclose the part of the index.html file where the Sencha Cmd compiler will operate. The only declarations that should be contained in this block are the script tags. The compiler will process all of the scripts within the x-compile directive, searching for dependencies based on the Ext.define, requires, or uses directives.

An exception to this is the ext-dev.js file. This file is considered to be a "bootstrap" file for the framework and will not be processed in the same way. The compiler ignores the files in the x-bootstrap block and the declarations are removed from the final compiler-generated page.

The first step in the compilation process is to examine and parse all the JavaScript source code and analyze any dependencies. To do this the compiler needs to identify all the source folders in the application. Our application has two source folders: Ext JS 4 sources in webapp/ext/src and 3T application sources in webapp/app. These folder locations are specified using the -sdk and -classpath arguments in the compile command:

sencha –sdk {path-to-sdk} compile -classpath={app-sources-folder} page -yui -in
-out {output-file-location}

For our 3T application the compile command is as follows:

sencha –sdk ext compile -classpath=app page -yui -in index.html
-out build/index.html

This command performs the following actions:

  • The Sencha Cmd compiler examines all the folders specified by the -classpath argument. The -sdk directory is automatically included for scanning.
  • The page command then includes all of the script tags in index.html that are contained in the x-compile block.
  • After identifying the content of the app directory and the index.html page, the compiler analyzes the JavaScript code and determines what is ultimately needed for inclusion in a single JavaScript file representing the application.
  • A modified version of the original index.html file is written to build/index.html.
  • All of the JavaScript files needed by the new index.html file are concatenated and compressed using the YUI Compressor, and written to the build/all-classes.js file.

The sencha compile command must be executed from within the webapp directory, which is the root of the application and is the directory containing the index.html file. All the arguments supplied to the sencha compile command can then be relative to the webapp directory.

Open a command prompt (or terminal window in Mac) and navigate to the webapp directory of the 3T project. Executing the sencha compile command as shown earlier in this section will result in the following output:

Opening the webapp/build folder in NetBeans should now show the two newly generated files: index.html and all-classes.js. The all-classes.js file will contain all the required Ext JS 4 classes in addition to all the 3T application classes. Attempting to open this file in NetBeans will result in the following warning: "The file seems to be too large to open safely...", but you can open the file in a text editor to see the following concatenated and minified content:

Opening the build/index.html page in NetBeans will display the following screenshot:

You can now open the build/index.html file in the browser after running the application, but the result may surprise you:

The layout that is presented will depend on the browser, but regardless, you will see that the CSS styling is missing. The CSS files required by our application need to be moved outside the <!-- <x-compile> --> directive. But where are the styles coming from? It is now time to briefly delve into Ext JS 4 themes and the bootstrap.css file.

Ext JS 4 theming

Ext JS 4 themes leverage Syntactically Awesome StyleSheets (SASS) and Compass ( to enable the use of variables and mixins in stylesheets. Almost all of the styles for Ext JS 4 components can be customized, including colors, fonts, borders, and backgrounds, by simply changing the SASS variables. SASS is an extension of CSS that allows you to keep large stylesheets well-organized; a very good overview and reference can be found at

Theming an Ext JS 4 application using Compass and SASS is beyond the scope of this book. Sencha Cmd allows easy integration with these technologies to build SASS projects; however, the SASS language and syntax is a steep learning curve in its own right. Ext JS 4 theming is very powerful and minor changes to the existing themes can quickly change the appearance of your application. You can find out more about Ext JS 4 theming at!/guide/theming.

The bootstrap.css file was created with the default theme definition during the generation of the application skeleton. The content of the bootstrap.css file is as follows:

@import 'ext/packages/ext-theme-classic/build/resources/

This file imports the ext-theme-classic-all.css stylesheet, which is the default "classic" Ext JS theme. All of the available themes can be found in the ext/packages directory of the Ext JS 4 SDK:

Changing to a different theme is as simple as changing the bootstrap.css import. Switching to the neptune theme would require the following bootstrap.css definition:

@import 'ext/packages/ext-theme-neptune/build/resources/

This modification will change the appearance of the application to the Ext JS "neptune" theme as shown in the following screenshot:

We will change the bootstrap.css file definition to use the gray theme:

@import 'ext /packages/ext-theme-gray/build/resources/ext-theme-gray-all.css';

This will result in the following appearance:

You may experiment with different themes but should note that not all of the themes may be as complete as the classic theme; minor changes may be required to fully utilize the styling for some components.

We will keep the gray theme for our index.html page. This will allow us to differentiate the (original) index.html page from the new ones that will be created in the following section using the classic theme.

Compiling for production use

Until now we have only worked with the Sencha Cmd-generated index.html file. We will now create a new index-dev.html file for our development environment. The development file will be a copy of the index.html file without the bootstrap.css file. We will reference the default classic theme in the index-dev.html file as follows:

<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>TTT</title> <link rel="stylesh eet" href="ext/packages/ext-theme-classic/build/resources/
css"> <link rel="stylesheet" href="resources/styles.css"> <!-- <x-compile> --> <!-- <x-bootstrap> --> <script src = "ext/ext-dev.js"></script> <script src = "bootstrap.js"></script> <!-- </x-bootstrap> --> <script src = "app.js"></script> <!-- </x-compile> --> </head> <body></body> </html>

Note that we have moved the stylesheet definition out of the <!-- <x-compile> --> directive.

If you are using the downloaded source code for the book, you will have the resources/styles.css file and the resources directory structure available. The stylesheet and associated images in the resources directory contain the 3T logos and icons. We recommend you download the full source code now for completeness.

We can now modify the Sencha Cmd compile command to use the index-dev.html file and output the generated compile file to index-prod.html in the webapp directory:

sencha –sdk ext compile -classpath=app page -yui -in index-dev.html
-out index-prod.html

This command will generate the index-prod.html file and the all-classes.js files in the webapp directory as shown in the following screenshot:

The index-prod.html file references the stylesheets directly and uses the single compiled and minified all-classes.js file. You can now run the application and browse the index-prod.html file as shown in the following screenshot:

You should notice a significant increase in the speed with which the logon window is displayed as all the JavaScript classes are loaded from the single all-classes.js file.

The index-prod.html file will be used by developers to test the compiled all-classes.js file.

Accessing the individual pages will now allow us to differentiate between environments:

The logon window as displayed in the browser

Page description

The index.html page was generated by Sencha Cmd and has been configured to use the gray theme in bootstrap.css. This page is no longer needed for development; use index-dev.html instead.

You can access this page at


The index-dev.html page uses the classic theme stylesheet included outside the <!-- <x-compile> --> directive. Use this file for application development. Ext JS 4 will dynamically load source files as required.

You can access this page at


The index-prod.html file is dynamically generated by the Sencha Cmd compile command. This page uses the all-classes.js all-in-one compiled JavaScript file with the classic theme stylesheet.

You can access this page at http://localhost:8080/index-prod.html

Integrating Sencha Cmd compiling with Maven

Until now we have executed the Sencha Cmd compile command from the terminal. It would be far better to execute the command during the Maven build process. The index-prod.html and compiled all-classes.js files can then be generated automatically every time a build is performed. The following plugin when added to the Maven pom.xml file will perform the following action:

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <id>sencha-compile</id> <phase>compile</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>C:\Sencha\Cmd\\sencha.exe</executable> <arguments> <argument>-sdk</argument> <argument>${basedir}/src/main/webapp/ext</argument> <argument>compile</argument> <argument>-classpath</argument> <argument>${basedir}/src/main/webapp/app</argument> <argument>page</argument> <argument>-yui</argument> <argument>-in</argument> <argument>${basedir}/src/main/webapp/index-dev.html</argument> <argument>-out</argument> <argument>${basedir}/src/main/webapp/index-prod.html</argument> </arguments> </configuration> </execution> </executions> </plugin>

The following are a few points to note:

  • The plugin is executed during the compile phase of the Maven build process.
  • The Sencha Cmd executable is defined with a complete filesystem path. Only then is it possible to build different projects with different versions of Sencha if required.
  • The ${basedir} property represents the full path to the root of the Maven project. Full paths are required for each argument as we are not executing the Sencha Cmd compile command from within the webapp directory.

The index-prod.html and all-classes.js files will now be updated every time a build is performed. The output of this plugin can be seen in the following Maven build log:

Adding the build version and timestamp

It is important to be able to identify different builds, not just the build version but also when the build was compiled. The project version is defined in the pom.xml file using the version property:

<groupId>com.gieman</groupId> <artifactId>task-time-tracker</artifactId> <version>1.0</version> <packaging>war</packaging>

Performing a Maven build will result in a WAR file being generated with the filename task-time-tracker-1.0.war; it is a combination of the artifactId and version fields with the .war extension.

In enterprise environments, a new release could be anything from a minor change (for example, Release Version 1.3.2) to a major release (such as Release Version 4.0). The exact naming conventions for the version value in use will depend on the enterprise organization. Regardless of the naming convention, it is important to identify when the build was made. This is obvious when the timestamp on the WAR file is examined, but not so obvious for the testers of the application, who only have access to the frontend. We recommend adding the release version and build timestamp to the Ext JS application to allow users to identify the version they are using. The logon window is an obvious place to display this information and we will add the build version and timestamp as shown in the following screenshot:

The first change that we will make is add two constants to the Application.js file in the init function:

init : function(application){ TTT.URL_PREFIX = 'ttt/'; Ext.Ajax.on('beforerequest', function(conn, options, eOpts){ options.url = TTT.URL_PREFIX + options.url; }); TTT.BUILD_DATE = '$BUILD_DATE$'; TTT.BUILD_VERSION = '$BUILD_VERSION$'; }

The TTT.BUILD_DATE and TTT.BUILD_VERSION fields define tokens (or placeholders) that will dynamically be replaced in the all-classes.js file during the Maven build. These tokens will not be populated for the index-dev.html file and the logon window for development will look like the following screenshot:

The token replacement with the correct build and timestamp is defined in the pom.xml file and requires several additions, the first being the property:

<properties> <endorsed.dir>${}/endorsed</endorsed.dir> <>UTF-8</> <>dd-MMM-yyyy HH:mm
<spring.version>3.2.4.RELEASE</spring.version> <logback.version>1.0.13</logback.version> </properties>

The property defines the format of the timestamp in the LogonWindow.js file. The second change is the addition of the maven-replacer -plugin:

<plugin> <groupId></groupId> <artifactId>maven-replacer-plugin</artifactId> <version>1.3</version> <executions> <execution> <phase>prepare-package</phase> <goals> <goal>replace</goal> </goals> <configuration> <ignoreMissingFile>false</ignoreMissingFile> <file>src/main/webapp/all-classes.js</file> <regex>false</regex> <replacements> <replacement> <token>$BUILD_DATE$</token> <value>${}</value> </replacement> <replacement> <token>$BUILD_VERSION$</token> <value>${project.version}</value> </replacement> </replacements> </configuration> </execution> </executions> </plugin>

This plugin examines the src/main/webapp/all-classes.js file and replaces the $BUILD_DATE$ token with the build timestamp defined by the Maven property ${}. The $BUILD_VERSION$ token is also replaced by the project version defined by the Maven property ${project.version}.

The final change required is to display these properties in the logon window. We will simply add a container below the toolbar in the LogonWindow.js file's item s array:

{ xtype:'container', style:{ textAlign:'center' }, html:' Version ' + TTT.BUILD_VERSION + ' built on ' + TTT.BUILD_DATE }

Running the project will now display the build version and timestamp in the application logon window of the index-prod.html page:

Building a slimmer WAR file

The generated WAR file, task-time-tracker-1.0.war, is very large in size at the moment; in fact, it is approximately 32 MB! The default behavior of the maven-war-plugin is to add all of the directories in the webapp folder to the WAR file. For production deployments we do not need a large number of these files, and it is best practice to trim down the WAR file by excluding the content that is not required. We will exclude the entire Ext JS 4 SDK and all of the Sencha Cmd-generated folders under the webapp directory. We will also exclude all the resources that are not applicable for production use, including the index*.html files used during development. The only file served by GlassFish will be the yet-to-be-created index.jsp:

<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>TTT</title> <link rel="stylesheet" href="resources/ext-theme-classic-all.css"> <link rel="stylesheet" href="resources/styles.css"> <script type="text/javascript" src = "all-classes.js"></script> </head> <body></body> </html>

You will note that the location of the ext-theme-classic-all.css file is in the resources directory, not in the deeply nested ext/packages/ext-theme-classic/build/resources location that is used in the HTML pages. The WAR file generation process will copy the appropriate content to the resources directory from the Ext JS 4 SDK location. This removes the need to include the SDK directory structure in the WAR file.

The production index.jsp file will now become our default welcome-file and we will adjust the WEB-INF/web.xml file accordingly:

<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list>

Running the application after this change in the web.xml file will ensure that the index.jsp file is served by GlassFish when a resource is not specified in the URL.

The changes required in the maven-war-plugin for building a slimmer production WAR file are highlighted in the following code snippet:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <warName>${}</warName> <failOnMissingWebXml>false</failOnMissingWebXml> <webResources> <resource> <directory>src/main/webapp/ext/packages/
<targetPath>resources</targetPath> <excludes> <exclude>ext-theme-classic-all-*</exclude> </excludes> </resource> </webResources> <packagingExcludes>.sencha/**,app/**,sass/**,overrides/**,
</configuration> </plugin>

The webResources definition will copy the content of the Ext JS 4 classic CSS theme to the resources directory. The targetPath property is always relative to the webapp directory; hence, we do not need a full path for the resources directory. The directory property is always relative to the root of the Maven project; hence, it needs a full path.

The packagingExcludes property lists all of the directories and files that should not be included in the WAR file. The ** symbol denotes that all of the subdirectories should be excluded. This will ensure that all of the Sencha Cmd-generated folders that are not required by our production WAR file will be excluded.

Executing the Maven build will now generate a WAR file of approximately 6.6 MB that contains only the files required for a production application.

Deploying the WAR file to GlassFish

Until now we have always deployed the 3T application to GlassFish via NetBeans using the Run Project command. In production environments we deploy applications through the GlassFish admin console or from the command line using asadmin. We will now learn how to deploy the task-time-tracker-1.0.war file to GlassFish using the admin console.

Opening the GlassFish admin console

Start GlassFish either in NetBeans or in a console window using the asadmin command. We recommend using asadmin as this is normally the way GlassFish is managed in an enterprise environment.

As we can see in the preceding screenshot, the default GlassFish Admin port value is 4848, as shown in the preceding screenshot, but it will be different if multiple GlassFish domains are configured. Open this location in the browser to display the GlassFish admin console:

GlassFish security basics

Working on the localhost will normally not prompt you for a password when using the default GlassFish installation provided by NetBeans. If you are prompted, the default username is admin with a blank password. The previous versions of GlassFish had a default password of adminadmin; at the time of writing, this is no longer the case. You should be aware that this may change again in the future.

Working on remote hosts where GlassFish is running on a server other than the browser will always prompt you for a username and password when you try to access the admin console. This is the situation with enterprise environments where different servers are usually running multiple instances of GlassFish. In this environment, remote access to the admin console will be disabled by default and you will only be able to access the admin console from the localhost. Allowing remote access from different clients can be enabled by executing the following commands on the host running the GlassFish server:

asadmin --host localhost --port 4848 enable-secure-admin asadmin restart-domain domain1

When enabling secure admin, you might be prompted with a message saying "your admin password is empty" (the default scenario). To solve this problem you will need to first change the admin password from the default (empty) password to another by using the following command:

asadmin --host localhost --port 4848 change-admin-password

You will then be prompted to enter the new password. Enabling secure admin will then be possible.

It is beyond the scope of this book to delve too deeply into the world of the GlassFish server administration. We recommend you browse the excellent documentation and user guides at

Deploying the WAR file using the admin console

Deploying a web application via the GlassFish admin console is a simple process. After logging on to the GlassFish admin console, click on and open the Applications node as shown in the following screenshot:

There may already be a task-time-tracker application deployed as a result of a previous NetBeans deployment (as shown in the preceding screenshot). If this is the case, select the checkbox next to the application name and then click on Undeploy.

Click on the Deploy… button and enter the following details:

The Local Packaged File or Directory That Is Accessible from GlassFish Server field will define the location of the task-time-tracker-1.0.war file on the local file system. If deploying to a remote server, you will need to use the Package File to be Uploaded to the Server option.

The Context Root field defines the URL path to the deployed application. We will deploy the 3T application to the context root.

The Application Name field defines the name of the application within the GlassFish server and is displayed in the application listing.

The Virtual Server dropdown defines the virtual server(s) that will be used to host the application. A virtual server, sometimes called a virtual host, is an object that allows the same physical server to host multiple Internet domain names deployed to different listeners. It is possible to select multiple virtual servers (if configured) from this list.

Click on the OK button to deploy the task-time-tracker-1.0.war file. This action will then return you to the deployed applications listing:

The task-time-tracker-1.0 application is deployed to the default Virtual Server with the name server and is accessible via the following two listeners:

  • http://localhost:8080/
  • https://localhost:8181/

This is the default virtual server/HTTP service configuration after installing GlassFish. Note that in a production enterprise environment that allows user logons, only the HTTPS version would be enabled to ensure encrypted SSL connections with the server. You can now access these URLs to test the deployment. Opening the https://localhost:8181/ link will result in a warning due to an invalid certificate as shown in the following screenshot:

This can be ignored and you may continue to the link by clicking on I Understand the Risks and confirming the exception (the exact message displayed will depend on the browser). Right-clicking on the logon page and selecting View Page Source will confirm that you are working with the production WAR file; this can be seen in the following screenshot:

Configuring HTTP listeners and virtual servers is once again beyond the scope of this book. We recommend you browse the appropriate documentation at

Deploying the WAR file using asadmin

It is also possible to deploy the task-time-tracker-1.0.war file using the asadmin command. This is a common situation in enterprise organizations where the GlassFish admin console is not enabled for security reasons. The syntax of the asadmin deploy command is:

asadmin deploy --user $ADMINUSER --passwordfile $ADMINPWDFILE --host localhost --port $ADMINPORT --virtualservers $VIRTUAL_SERVER --contextroot --force --name $WEB_APPLICATION_NAME $ARCHIVE_FILE

This command must be executed on a single line and each uppercase variable name prefixed with $ must be replaced with the correct value. The exact syntax and parameters may depend on the environment and we will not go further into the structure of this command. If you are interested in learning more about this command, you may browse the detailed documentation at; please note that this document refers to the GlassFish 3.1 reference manual.

Further deployment information and reading

The document at contains extensive and detailed explanations for deploying applications to the GlassFish 4 server. This document is more than 200 pages long and should be consulted for any deployment-related questions that have not been covered in this article.

GlassFish performance tuning and optimization

The definitive guide to performance tuning and GlassFish server optimization can be found here at

This guide includes sections on tuning your application as well as tuning the GlassFish server itself. Configuring aspects such as thread pools, web container settings, connection pools, garbage collection, server memory settings, and much more are covered. We recommend you consult this document to learn as much as possible about this important aspect of enterprise development and deployment.


We have compiled our Ext JS 4 application into a single all-classes.js file for production use and added the build version and timestamp to the LogonWindow.js file. We then reduced the size of the Maven-generated task-time-tracker.war file by removing all of the resources that were not required for production deployment. This production WAR file only contains the resources required by the application at runtime and excludes all the Ext JS 4 SDK resources and directories that are not required. We then examined the GlassFish deployment process and deployed the task-time-tracker-1.0.war file via the GlassFish admin console. There is still much more for the you to learn about the GlassFish server, but the entrée has been served!

Our Ext JS and Spring development journey now comes to an end. This book has covered an enormous amount of territory and provided a solid foundation for enterprise application development using these key technologies. We sincerely hope that your development journey will be easier and more rewarding as a result of reading this book.

Resources for Article:

Further resources on this subject:

You've been reading an excerpt of:

Enterprise Application Development with Ext JS and Spring

Explore Title