Skip navigation.
Home

Running Maven Built Web Applications Directly From Intellij IDEA

Intellij IconHere's how you can run maven built web applications directly from within Intellij IDEA 8. Once you run this way, you completely eliminate the code, build, deploy, restart cycle just when you want to make a change... you can even change classes on the fly (hot swapping).

I pretty much only run in debug mode now. Debugging is really nice because the dependent source files are linked up and downloaded automagically by maven on the fly and class changes via hot swapping really makes you productive. The archetype selection in the project creation wizard came with version 8 but the rest of the guide will work with versions 6 and 7 as well. I used the appfuse-basic-spring archetype as the web application but any web app built with maven should work in a pretty similar way.

Create Maven Module

First, we need a project. There's nothing special to note here with the exception of the name field. The name field cannot contain a space. If it does, Intellij doesn't start up tomcat properly and you get this ClassNotFoundException on logging/properties.

Create new project

Choose Maven Archetype

You can type in what you want to for your particular project here. Then click Finish.

Choose Archetype

Build Project with Maven

Next you need to build the project to make the output directories.

Run Maven Package

Click Edit Configurations

There's a button on the toolbar or you can find it by going to Run --> Edit Configurations. After you click the plus sign and pick local tomcat server you'll see this

Run/Debug Configurations

Pick Application Server

If you've already configured an application server for Intellij, you can just choose it in the dropdown menu. Otherwise you'll need to configure one. After you click Configure... you'll see this screen:

Create Local Tomcat Server

If you haven't installed Tomcat locally you'll of course need to do that. Then click the plus sign and pick the tomcat home and Intellij will figure out the rest.

After you hit ok, you'll be back to the Run/Debug Configurations menu. Now you can choose the server from the dropdown and the Startup page: should be filled in with whatever port your Tomcat server has been configured to use.

After Tomcat Server Config

Click on Deployment Tab

This is where you choose the deployment source and application context for the web facet within the application. First click on the Web Facet: Web module in the middle pane and check the Deploy Web Facet 'Web' checkbox.

Click Deployment Tab

Click the Configure... button.

Configure the Deployment Source

Uncheck the Create web facet war file and choose Create web facet exploded directory instead.

Java EE Build Settings Default

Click the ellipses (...) button to choose the exploded directory:

Select Web Facet Exploded Directory

Choose the location under the target folder where maven built the war. It is going to be named using artifactId-version that you chose when you created the project in the first place. This information is stored in the pom.xml file so you can change it whenever you want. If you do change it go back to the Build Project with Maven step after you have done so.

Click Ok. Then Click Ok to close the Deployment Source window.

Finish Deployment Tab

Now you can select the Deployment Source and set your application context.

Finish Web Facet Deployment

Click Ok.

Run/Debug the Application

You should see the server startup successfully

Click the Run Button

Login to the Application

See Login Page

Login to the application

Hot Swapping

If you've started up in debug mode (highly recommended), change a class in the class path and make the project (Apple+F9) or compile the specific class you've changed (Apple+Shift+F9). You should be presented with this popup:

Redeploy Application Popup

Make sure you click No on this dialog box. If you click yes, hot swapping won't work. I usually check Do not show this dialog in the future as well.

That's it! Now when you change classes and JSPs you can just compile and they will be hot swapped with resources on the running server.

does not work for me

Seems like the pom.xml sets up build properties that various appfuse configuration files need, for instance applicationContext-dao.xml

INFO: Starting Servlet Engine: Apache Tomcat/6.0.18
ERROR [main] ContextLoader.initWebApplicationContext(215) | Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'sessionFactory' defined in class path resource [applicationContext-dao.xml]: Circular placeholder reference 'hibernate.dialect' in property definitions
	at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:268)
	at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:75)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:554)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:528)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:363)
. . .

This is for appfuse-struts-basic with the full-source plugin ran. Intellij 8.0.1, OSX 10.5.6, System 1.5 JVM

Matt Fleming's picture

The props files are sometimes a pain

The key to this is to figure out which prop file is being put into the output folder. When doing the full-source option, some of the files seem to be in repeated (in different source locations). I would find the source of the file that is being put into the target web app directory and then alter that file to not use dynamic substitution. I haven't done the struts basic with full source but I'm sure it can work.

-Matt

I'm having that problem. My

I'm having that problem. My hibernate cfg properties aren't being injected b/c maven package cmd outputs 3 copies of the spring xml cfg files. The dynamic substition occurs in 2 copies, but not in the copy that is used when tomcat boots.

Anyone have a suggestion?

ok, I found the solution:

ok, I found the solution: maven-war-plugin
http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html

You can jump down to the heading for Filtering.
This will allow you to force the maven dynamic substitution into the spring config files that are referenced during tomcat's boot sequence.
This worked for exploded directory and war.

Here's how I used it. With this addition, Matt's example works perfectly. (thanks!)

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1-alpha-2</version>
        <configuration>
       <filters>
             <filter>src/main/resources/filters/${env}.properties</filter>
       </filters>
          <webResources>
              <resource>
                <directory>src/main/webapp</directory>
                  <includes>
                  <include>WEB-INF/myspring-context-files-*.xml</include>
                  <include>WEB-INF/hibernate*.xml</include>
                  <include>WEB-INF/web.xml</include>
                </includes>
                  <filtering>true</filtering>
              </resource>
          </webResources>
        </configuration>
      </plugin>

Pom versions and exploded directory location

The Maven integration is really nice, one thing that I would like to see is the following:

Whenever I upgrade the pom version, the exploded directory location is rendered invalid (e.g. the location remains 'webapp-1.0-SNAPSHOT', while I've upgrade the POM to 1.1).

Either IDEA should automatically update the exploded location (great, but perhaps a little too intelligent for my taste) or we should have the possibility to use a string template (e.g. target/webapp-${pom.version}).

Here's a workaround to add

Here's a workaround to add to your pom. I used ROOT because my particular app is always going run from root. However, you could use whatever application context you want in 'finalname' so that you don't have to change your Intellij Tomcat configuration each time you change your POM version.

   <build>     
        <finalName>ROOT</finalName>
   </build>

Bringing back the final dialog in IntelliJ

If you accidentally said Yes to the final "Deploy facets for run configuration Tomcat" dialog box AND checked the "Do not show this dialog again", how can you get it back?

It should be a simple preference somewhere in IntelliJ settings but the location of that setting has eluded me for quite a while...

thanks!

Matt Fleming's picture

I have looked for it and cannot find it

If you find out (maybe we should ask Jetbrains?) let me know. You could always just whack the intellij project files and rebuild them from the pom. You'll have to do the server stuff again but it only takes a few minutes.

-Matt

Haha, so i'm not the only one

That's exactly what I did. But it just seemed to have all the sophistication of an Ox cart at a sports car convention... I'll post it here if I do find out.

thanks

PS: sorry, meant to hit reply but instead ended up creating a new thread.

Matt Fleming's picture

Here's the answer that I got from jetbrains

Settings | Compiler | Deploy web applications to server after compilation => Change to Ask

-Matt