IntelliJ IDEA - A Web Application Tutorial

- Damodar Chetty

- January 11, 2008

- Last Updated: March 11, 2008

 

I recently had an opportunity to road test IDEA 7.x, IntelliJ's latest version of their hugely popular Java IDE. This wasn't my first brush with IDEA, as I had used it extensively at version 4.x, but had found it painfully slow on a resource constrained laptop. On the advice of friends, I decided to try out Eclipse, and it was love at first build.

 

Well, turns out that IDEA is the defacto standard where I work, and developer workstation configurations are standardized for that IDE, including code inspection templates. Since I'm not an IDE fanatic, I decided it was time to leave the familiar behind, and give IDEA a whirl.

 

As a web developer, the major challenges with any new IDE are to:

(a) see how quickly you can become familiar with how the IDE views your code base,

(b) figure out how to deploy a web application to the target web container/application server, and

(c) set up hot deployment for your code and JSPs.

 

With that in mind, I set about creating a toy web application in IDEA and then took it apart to see how it all came together. Here are my learnings from my experiences. Hopefully, documenting this will save you a few scraped knees.

 

Project organization within IDEA

IDEA looks at your code base in terms of projects, modules, and libraries.

 

The basic unit of work is the module, which is a set of source files, unit tests, build scripts, documentation, deployment descriptors, etc. that together define a logical unit of software. There are a number of module "types", but for our purposes here, we deal with a web module which extends the basic Java module with support for deployment descriptors, application server publishing, etc. Each module is represented by a XML file (.iml).

 

A library is a peer entity to a module, and is typically represented by a JAR file that contains classes that you want to add to the classpath. Libraries have a scope, and those defined within a module are only available to that module; those defined within a project can be accessed by all the modules in that project; and those defined globally are available to all modules contained within any project on your system.

 

A project encapsulates all the modules and libraries that are required by the system you are developing. It also provides a central location to specify configuration settings that apply across all the modules that comprise a project, e.g., the JDK to use, compiler settings, etc. It is represented by a project (.ipr) XML file.

 

A typical project may consist of a single module that contains all your source files, and one or more third party libraries that you intend to use.

 

[An additional workspace settings file (.iws) records various information regarding your Run/Debug configurations, window placement, etc.]

 

Web Module Configuration Parameters

The next step is to become familiar with the configuration options that you will encounter when setting up a web module. It is important that you understand what these settings signify, so we'll make this short detour before we begin actually setting up our project.

Project related properties:

         Project name: This is the name used for the project file (.ipr)

         Project file location: This is the path to your .ipr file.

 

Module related properties:

         Web module name: the name of the module, defaults to the project's name.

         Web module file location: This is the path to your .iml file, defaults to the project file's location.

         Web module content root: the path to the top folder that contains all the files that comprise this module (sources, tests, rsources, etc.)

         Root Source folder: This folder is relative to your web module's content root, and is where your source files will be located. It corresponds to the default unnamed package, and your package hierarchy will extend below it. All source files contained under this folder will be compiled into class files when you build this project.

         Project compiler output folder: All your compiled class files will be written out to a package hierarchy under this folder. Can be defined at a module specific level.

 

Deployment related properties:

         Application Server Specific Descriptor: For Tomcat this is a context fragment (context.xml) that is placed under your META-INF folder.

         Deployment root, aka Web Module Exploded Directory: This is the path on your local disk which maps to the deployment root on the application server. I.e., this folder will contain the WEB-INF folder.

o        Modules and Libraries to Package and a Packaging Method: Specifies the destination folder for all compiled class files, resources, and JARs that belong to a module. This is relative to the deployment root. Typically, your class files and property/XML files will be copied to /WEB-INF/classes, and your libraries will be copied to /WEB-INF/lib.

o        Web resource directory: Defines the location of the web resources (HTML, JSP, images, etc.) of your module, and describes the destination folder on the web container, relative to the deployment root.

 

 

Setting up your Application Server

In this example, we will be deploying our application to Tomcat. In order to use Tomcat with IDEA, you must first install the Tomcat Integration plugin using the Plugins manager.

Next, register a Tomcat installation with IDEA by clicking File > Settings > Application Servers.

Click the Add button, and specify your Tomcat installation directory. If you don't have Tomcat installed, please visit tomcat.apache.org for a recent distribution.

 

IDEA prompts for the Tomcat Home and Base directory fields (which are the same), which is where you unpacked the Tomcat distribution you downloaded earlier.

 

 

Setting up an IDEA Web Project

This is where the real story begins. So, fire up IDEA, and begin by clicking Create New Project.

 

Choose the Create project from scratch option, and click Next.

 

Next, we specify our project's name and location of the .ipr file. For a single module project, the module's name and .iml file location default to the same as for the project.

We also specify the module's content root, which is the file system location within which all content related to this module (source files, resource bundles, deployment descriptors, output class files, etc.) can be found.

 

Specify the root of the folder that contains your Java source files. The root source folder is relative to your module's content root folder. This folder is considered the root of your package hierarchy (i.e., it is your unnamed default package), and is where the source files are located (for an existing project) or will be located (for a new project). Source files under this folder are compiled on a build.

 

 

Finally, choose the Web Application facet, and click Finish. To keep it simple, we won't specify any of the optional frameworks (e.g., Struts or JSF).


 

This drops you off in the main IDEA window, with the appropriate folder structures created based on your selections.

 

At this point, lets create a new Class file com.ses.Hello as follows:

package com.ses.hello;

public class HelloWorld {

public static String getText() {

return "Hello world!";

}

}

 

Edit your index.jsp file to add some dynamic content to your web application:

<%@ page contentType="text/html;charset=UTF-8" language="java" import="com.ses.hello.HelloWorld" %>

<html>

<head><title>Simple jsp page</title></head>

<body>

Place your newer content: <br>

<% String s = HelloWorld.getText(); %>

<%= s %>

</body>

</html>

 

The views now change to:

 

 

If you were to venture out into your file system, you'd see the following structure:

 

 

 

 

Observing this structure shows that IDEA uses sane defaults for folders that you didn't explicity specify, such as the deployment root. To see how this magic happens, we need to explore the project settings that can be accessed using File > Settings (Ctrl-Alt-S).

 

On the General tab, we first note the specification of a default path for all compiler generated output, i.e., your compiled Java classes.

 

 

Click on Modules and check out the Sources tab. Selecting the dcweb module displays its source folders. As expected, the sources are rooted at src. This adds color coding to our Windows Explorer structure that we saw earlier, based on whether the folder contains normal source files, whether it contains unit test sources, or whether it is to be excluded from consideration (ie., does not contain sources).

You can also add other content roots (in addition to src) by clicking "Add Content Root".




Click on the actual web application to see additional properties that apply to web modules.

 

Lets first create a Tomcat context fragment by clicking Add Application Server specific descriptor.

 

This generates a context.xml which indicates that this application is available as the default (ROOT) web application in Tomcat.

<?xml version="1.0" encoding="UTF-8"?>

<Context path="/">

</Context>

The Deployment Descriptors section is automatically updated to reflect this fragment:

 

The Modules and Libraries to Package shows a list of all modules and libraries that need to be packaged with this web application in order for it to function properly. E.g., if the web module were to rely on a 3rd party library, that library would have to be packaged within the WAR for the web app to work.

This list includes:

         Modules to package
The module dependencies in the Dependencies tab.

o        "Do not package" will not include the module in the final web app even though it is required;

o        "Copy module output to" copies the compiled Java classes to the specified directory relative to the deployment root (WEB-INF\classes);

o        "JAR module output and copy file to" Jars the output to WEB-INF\lib instead; and

o        "JAR module, link via manifest and copy to" will also add it to the manifest.mf.

         Libraries to package
The library dependencies (or Jars) marked in the Libraries tab.

o        "Do not package" will not include the JAR in the final web app even though it is marked as required;

o        "Copy Files To" copies the JAR to the specified directory relative to the deployment root - usually WEB-INF/lib;

o        "Link via manifest and copy files to" to copy it to the specified directory relative to the deployment root (usually /). A link to the JAR is added to the META-INF\manifest.mf in the web module.


Web Resource Directories specify the location of your web resources (HTML, JSP, CSS, images, etc.) This section maps folders on your local file system to folders relative to the deployment root for this web application (which is specified on the Java EE Build Settings tab). E.g., here, any JSP files in d:\testing\dcweb\web will be copied directly to the web application's deployment root.

 

This indicates where your web application's class files reside.

 

 

Web applications can be deployed as a WAR file or as an exploded directory - which is the path on the application server for the web module's exploded directory (i.e., the deployment root).

 

Running the web application




Press the + button and add a Local Tomcat Server configuration:

 

Pick Tomcat 5.5.20 as the application server. This sets the startup page appropriately.

 

Pick the application to deploy:

 

Click Finish.
 

 

Your application can now be deployed. Verify that everything is working by clicking the Green triangle (run) or the bug (debug) buttons. A browser window should open up with your index page displaying the Hello World! Message.

 

Hot Deploying changes to the Web Application

Next, lets make sure that we can hot deploy changes to the Java source files, or to JSPs. In order to make this happen, on the Project Settings> Compiler tab, set the Deploy web applications to server after compilation to Never.


 

 

In your IDE Settings> Debugger make sure that you have Reload classes after compilation set to Always.

 

To experiment with hot swapping of code, do the following:

1.       Change the static text displayed in index.jsp, and save the file. Now refresh the page (you may have to clear your browser's cache) and you'll see the changes have taken.

2.       Change the output from HelloWorld.getText() and perform a Build>Compile HelloWorld.java (Ctrl-Shift-F9). Refresh the page and you should see your change.

 

That's it. It took me a while to get all of this going (particularly the hot deploying). My next task is to go beyond this toy program and tackle the actual project code base, but well that's a story for another day.