Automate Java Dev Setup | IntelliJ | Maven | Cargo

You want to automate the provisioning of a Java Web (REST) development stack. We will employ Maven, IntelliJ, Cargo, Tomcat, Selinium on either a Windows or Linux platform.

The resulting application must be buildable and runnable inside IntelliJ, by Jenkins, and on the Windows and Linux command lines.

Provisioning a Stack for Java WebApp Development

You can use Chocolatey to automate installation on Windows, whilst using apt-get or yum on Linux. These are the steps required to achieve the development stack

  • install IntelliJ and note the install folder.
  • install Maven 3, configure env vars, settings.xml and IntelliJ.
  • dynamically consumed through meta strings in INI file values
  • consumed by templates through auto evaluated placeholders
  • grouped as global, common or plugin-specific
  • re-evaluated (reproduced) to create another eco-system

1. Install IntelliJ

Use Chocolatey to install IntelliJ. We will then return to configure it after maven has been installed.

2. Install Maven 3

Use Chocolatey to install Maven and powershell to setup the environment variables.

Maven’s Environment Variables

Once Maven is installed setup two, and edit one environment variable. (On Windows go to Start, Computer, right click Computer, Properties, Advanced System Settings, Environment Variables then New or Edit.

  1. M2 create the environment variable with path to maven bin.
  2. M2_HOME create env var with path to maven install dir.
  3. change the PATH env var by adding path to maven bin.

Maven’s Settings XML File

The Maven settings xml file will tell IntelliJ (and the maven command line commands)

  1. of Nexus or Maven Central – repos from which to fetch dependencies.
  2. which local folder to cache the downloaded Jars and Wars
  3. which Nexus or Artifactory repository to deploy built artifacts to.

Best practise is to only deploy artifacts into Nexus from a CI server like Jenkins. Artifacts are deployed only after passing the full raft of tests and quality inspections.

3. Pull IntelliJ Options From Git or S3

We prefer to keep IntelliJ configuration in its own Git (or S3) repository.

We Git clone it to a local folder. The next step tells IntelliJ (via its idea.config.path parameter in the idea.properties config file) where to find its configuration.

If while using IntelliJ you make configuration changes (like font, spacing, templates) – you must remember to git commit and git push.

4. Tell IntelliJ where its Options folder is.

We automate the IntelliJ installation and part of this requires changing idea.properties in IntelliJ’s install folder.

#———————————————————————
# Uncomment this option if you want to customize path to IDE config folder. Make sure you’re using forward slashes.
# To Undo the Below Just RE-COMMENT IT.
#———————————————————————
idea.config.path=@[ide.conf.home.dir]

The dev stack provisioning scripts alter idea.config.path to the a location ear-marked for this IntelliJ instance.

5. Configure IntelliJ with IML and Maven Locations

We prefer to keep IntelliJ configuration in its own Git (or S3) repository. We pull it down to the location set in the above idea.config.path parameter in the idea.properties config file.

The IntelliJ options/project.default.xml

We now alter the options/project.default.xml file telling IntelliJ to

  • put its IML project files in a non-Git working copy folder.
  • read the maven settings.xml file from a specific location.
  • use the maven installation at the specified base folder.

The options/project.default.xml file is how IntelliJ allows us to deliver the 3 configurations noted below.

Folder for IntelliJ .iml files

<option name=”dedicatedModuleDir” value=”@[ide.intellij.iml.dir]” />

Specify Maven Settings XML File Location

<option name=”userSettingsFile” value=”@[maven.settings.xml]” />

Specify Maven Installation Folder

<option name=”mavenHome” value=”@[maven.install.dir]” />

You’ve now provisioned the big beasts. You’ve setup Maven and you’ve told IntelliJ where Maven is.

Use this series to setup your own Killer Web App with an open source JAVA, Tomcat and Maven architecture.

We are injecting quality into the web application in a simple and assured manner. Each step automates something you need to do frequently, or addresses recurring problems (like broken links) that hound every web developer.

1. Install a Web Application Seed

Mission – To plant a baby web application seed that you can build, test, deploy and visit with a web browser.

The first step is to use a maven archetype for the basic directory setup. After that we make some important additions to your web application’s pom.xml file. This leg up allows you to hit the ground running thanks to the now popular convention over configuration pattern.

Note that there is no need to install Tomcat (nor glassfish nor JBoss …). This seed will download and install your preferred application server, start it, run the automated integration and system tests, and then stop it.

We will get the application seed up and running in 3 steps.

  • 1.1 Setup – unravelled by a maven archetype
  • 1.2 Checkupcheck up on the key build commands
  • 1.3 Link Up – visit your web app to c4urself

1.1 – The Setup

We will use Maven archetypes to create a simple working web application within Tomcat that functions with the IntelliJ IDE (and hot reloading), the Jenkins Continuous Integration Server and the Nexus repository manager.


mvn archetype:generate -DgroupId=com.your.app -DartifactId=explorer -Dversion=0.00.000 -DarchetypeGroupId=org.codehaus.cargo -DarchetypeArtifactId=cargo-archetype-webapp-single-module -DinteractiveMode=false

Notice that two sets of maven coordinates. The first is your application and the second is the cargo plugin that will generate a working one page website.

  1. groupId is com.your.app whilst archetypeGroupId is org.codehaus.cargo
  2. artifactId is explorer whilst archetypeArtifactId is cargo-archetype-webapp-single-module
  3. version is 0.00.000 whilst (no version required – the best will be selected)

And notice that you can change the archetype artefact identifier in order to produce similarly different starting points – most notably

  1. cargo-archetype-remote-deployment creates an app that pushes the generated war file into a remote (tomcat, jetty …) container
  2. cargo-archetype-webapp-functional-tests-module creates a functional testing application solely for testing other web apps
  3. cargo-archetype-daemon will run a daemon process on a remote server to build and deploy (not recommended).

As long as you’ve provided the above 5 parameters, you can safely switch off the interactive mode. This allows you to script the web application generation.

Our single module option will create an application that can be built, tested and deployed locally and remotely into the major servers including Tomcat, Jetty, JBoss, WebLogic, GlassFish



1.2 – The Check Up

Let’s check up on the maven archetype that has laid our web application’s groundwork. Note that most of the commands below will download a container, install it, deploy a war file into it, start it, run the functional tests against it and stop it.

  1. mvn clean install – check up on a WAR file in the local maven repository
  2. mvn clean verify – check a WAR file is built and tested into (default) “Jetty” container
  3. mvn cargo:run – this will push the WAR into Jetty allowing you to check up with a browser

The above commands are okay – but we need more power. You may need to run

  1. mvn deploy – deploy into a Nexus repository after the WAR file build and test
  2. mvn install -P tomcat8x – run the functional tests against Tomcat 8
  3. mvn cargo:run -P tomcat8x – allow us to test the war file against Tomcat 8

It is time to clean out the POM. The cargo app goes overboard and a bloated pom.xml harms our productivity. Also we don’t want the target build files within the project. It is easier to interact with Git, Subversion and IDE’s without the dreaded target folder in our midst.

Also we want to specify exactly what application server and exactly which version to use in order to mimick our production environment.



1.3 – The Url to Link Up

If in the maven archetype generation command you setup an artifactId of explorer and a version
of 0.00.003 your WAR file comes out named explorer-0.00.003.war.

http://localhost:8080/explorer-0.00.003

If you pushed this WAR file manually into Tomcat or Jetty your URL would be http://localhost:8080/explorer-0.00.003

http://localhost:8080/explorer

However, if you use the mvn cargo:run command it handily exposes just the artifact ID without the version tag. This makes it easier for you to manually visit the website without worrying about typing out the version number.

A small matter but productivity is the name of the game – and every little helps.

A Change of Port

Port 8080 is busy as it is the default port for Jenkins, Tomcat, Jetty and many other “usual suspects”.

Look in the POM at the tomcat8x profile and you’ll see the port is changed to 8899. If you’ve used this the url changes to

http://localhost:8899/explorer

Last Word » Portability and Version Control

Portability

The above commands (for example mvn cargo:run) have all been tested

  1. on the Ubuntu command line in a local server and virtual machine
  2. within the Amazon AWS EC2 cloud for both Linux and Windows
  3. on the Windows DOS and PowerShell command lines in Windows 7, 8 and 10
  4. within the Jenkins Continuous Integration Server build
  5. for a WAR file deployment into the Nexus Repository Manager build


Version Control

Don’t checkin your fledgling web application. It is putting the target directory within the what will be our working copy. You don’t want this.

A team of two or more people makes it annoying to manage .gitignore and .svnignore tactics. Someone someday is going to check classes and jars in and someone will check them out and waste half a day trying to understand why it worked last thing yesterday but fails first thing today.

So let’s tell maven to put the build output classes elsewhere.

2. Move build output (target classes) folder

Our application directories will be version controlled so we do not want the target classes (main and test) polluting our SCM repository. You can use .svnignore or .gitignore but we prefer to move them to a runtime area off the user’s home directory. We’ll move the (IntelliJ) IDE settings files here too.

This pom.xml snippet that moves the build output out of the way.


        <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
        | + | Configuration of build properties and attributes. Its dependencies. The folder layout. And more. | + | 
        ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 
        <build> 
                <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
                | + | Build Business Websites follows an Artifact Naming and Location Convention. | + | 
                +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 
                <directory>${user.home}/asset-plate/wapp.dialogs.archive.home</directory> 
                <finalName>${project.artifactId}-v${project.version}</finalName> 
                <outputDirectory>${user.home}/asset-plate/wapp.dialogs.main.classes</outputDirectory> 
                <testOutputDirectory>${user.home}/asset-plate/wapp.dialogs.test.classes</testOutputDirectory> 
        </build>

After you change the pom.xml run this command and check that the build output folders have received the class file.

mvn clean install

Maven will also put a WAR file into the local repository location which is usually in the .m2\repository folder tree. Did you see the .WAR file? Let’s take a quick peek!

Inside the Web Application WAR File

Well done – we got started! Now


    <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
    | + | The deploy phase publishes artifacts to the snapshot or release libraries. | + | 
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 
    <distributionManagement> 
 
            <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
            | + | We [PUBLISH] production quality artifacts to the [RELEASES] library. | + | 
            ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 
            <repository> 
                    <id>publish-to-library</id> 
                    <name>Releases Library</name> 
                    <url>https://www.build-business-websites.co.uk/library/content/repositories/releases</url> 
            </repository> 
 
            <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
            | + | We [DEPLOY] snapshot build artifacts to the [SNAPSHOTS] library. | + | 
            ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 
            <snapshotRepository> 
                    <id>snapshots-library</id> 
                    <name>Snapshots Library</name> 
                    <url>https://www.build-business-websites.co.uk/library/content/repositories/snapshots/</url> 
            </snapshotRepository> 
 
    </distributionManagement> 


Here are 10 (Quality) DevOps features to kick start your Java web application development – let’s start as we mean to go on! These features will increase your productivity, shorten your code test build cycle, and thanks to continuous integration and continuous delivery, your application will enjoy a responsive, robust edge, with timely turn around times for new feature implementation.

From the get-go we state our 10 “DevOps” fashioned requirements for the web application. We need to

  1. create a correctly laid out web application using Maven’s archetypes
  2. move the target classes directory out of our version controlled application tree
  3. Create an IntelliJ IDE “ready to import” project for our web application
  4. Use hot reloading so that IDE changes are immediately reflected in the browser (no build step)
  5. Automatically download Tomcat and deploy our web application within it with one command
  6. Create system tests to smoke test the application by requesting key pages
  7. Ensure that our Jenkins Continuous Integration Server checks out our project, builds and tests it.
  8. Publish the built and tested WAR file to our Nexus artifact repository
  9. Release the published WAR file from Nexus and into our production server with one command.
  10. Activate a parallel release that deploys PDFs and larger media into an Amazon Cloud S3 bucket.

Inside the webapp let’s use Freemarker for managing and binding the HTML templates as JSP is now a little outdated. Also, let’s enable our users to authenticate and register and/or enter with OpenID so that they can reuse their Facebook, Google, and/or Twitter credentials.

Your Web App’s Must Have Features

We will use Maven archetypes to create a simple working web application within Tomcat that functions with the IntelliJ IDE (and hot reloading), the Jenkins Continuous Integration Server and the Nexus repository manager.

Productivity, Productivity, and Productivity

Productivity is the most important consideration in JAVA web application development. That’s why we will not Work, REST or Play – no Spring FrameWork, almost no RESTful services, and no Play2.

Goodbye – “Switching To Browser”

Even with hot reloading you must switch from IDE to browser, hit refresh – login – then walk through a few screens to meet with an exception.. This approach is too slow.

I will show you how to press a key and get and instantly receive feedback from a “functional” test. You must DIY to check the look and feel but most of your code » feedback cycles revolve around functionality. Furthermore, the compile test loop can be run

  1. from your IntelliJ or Eclipse IDE
  2. from the Windows and/or Linux command line
  3. from within the Jenkins CI server

And all the above use the same version of Tomcat, Jetty, JBoss and GlassFish that you run in production. Switching containers and versions is easier than switching lanes on an empty freeway.

Hello – “WordPress and Java”

Yes WordPress. WordPress and Java feel like Church and State, chalk and cheese, never the twain shall meet. Actually they work well together.

WordPress raises productivity because it separates look and feel (through themes), from website functions (through plugins), from content management and navigation (through categories and tags).

WordPress can manage login, comments, headers and footers, layout and so on. Java managers the domain model, transactions and interactions with data sources.

Who Does What? – “WordPress and Java”

We don’t need Spring MVC because we don’t need the “V” – no views, no templates. We don’t need controllers per se, mapping requests to model services is what RESTful services do brilliantly. So who does what?

Your JAVA app receives a GET request (say for Products) from the middle of a WordPress page. It replies with a JSON representation of the products. WordPress renders it.

When POST data is submitted – your JAVA web app saves it and WordPress replies saying all is good.

Responsive Website? – “WordPress and Java”

Your website becomes mightily responsive and efficient. The web server serves images and static pages directly. WordPress handles comments interactions, logins, whilst your Java app manages the domain and persistence models.

This is an SOA architecture. Your Java app can service external XML and web service requests as well as requests from your internal website.

Views are taken off a web application developer’s plate. This extraction is big and results in a large productivity increase.

Leave a Reply

Your email address will not be published. Required fields are marked *