Create and test a simple Java project with Maven and Intellij

How to create and test a simple Java project with Maven and Intellij.

Step 1

Use maven to create the project skeleton.

Either

mvn archetype:generate

and pick Option 15 – maven-archetype-quickstart

Or

mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create \
    -DgroupId=net.olioinfo \
    -DartifactId=java_simple \
    -DarchetypeArtifactId=maven-archetype-quickstart \
    -DarchetypeGroupId=org.apache.maven.archetypes

Step 2

  • Import into Intellij as a Maven project.
  • Make sure that the SDK is set to a JAVA SDK
  • On the Run menu, edit the Configurations to add a Junit test suite
    • Select ‘Test all in package’
    • Specify package
    • Pick the top-level project directory as the working directory
    • Ensure that ‘Make’ and ‘Build artifacts’ are checked
    • Save
  • The top two entries on the Run menu are now available
    • The top ‘Run’ menu entry will run the last configuration applied
    • The top ‘Debug’ menu entry will debug the last configuration applied
  • Maven introduces two more entries below the top two entries on the Run menu
    • ‘Run’ will run the configured maven goal (from the last configuration applied).
    • ‘Debug’ should run maven in debug mode. Doesn’t seem to work
  • All the standard maven targets work from command line. They will also function when included in an Intellij run-time configuration.

Intellij Idea 9 – Building a Java webapp + missing dependencies

To build a Java webapp in Intellij Idea 9. follow the standard procedure documented in various places (to be supplied).

When the sample classes are examined, there will be undefined dependencies or imports for all the servlet – and any other J2EE – dependencies.

This is a change from Intellij 8, which included the J2EE libraries as compile-time options. To correct this there are two choices:

  • Java 5  – Use the attached java 5 – J2EE jar and add as a compile-time dependency (taken from Intellij 8 )
  • Java 6 – Use the attached java6 EE jars and add as a compile-time dependency (taken from glassfish v3 dependencies)

Intellij Idea 9 – Importing a Maven Groovy project

To import a Maven Groovy project into Intellij Idea 9:

  • File > New Project
  • Select ‘Import project from external model’.  Click [Next]
  • Select ‘Maven’. Click  [Next]
  • In the root directory window, navigate to the top-level directory of the Maven-Groovy project. Click [Next]
  • Accept default offered for ‘Select Maven projects to import’. Click [Next]
  • Accept default offered for project name. Click [Finish]
  • All done!

Double-click on the video player to open on YouTube.

Maven – Setting up a Groovy project

To set up a basic Groovy project using Maven (all on the same line):

mvn archetype:generate \
  -DarchetypeGroupId=org.codehaus.groovy.maven.archetypes \
  -DarchetypeArtifactId=gmaven-archetype-basic \
  -DarchetypeVersion=1.0-rc-3

Then fill in the information as for any Maven project.

An Example:

mvn archetype:generate \
  -DarchetypeGroupId=org.codehaus.groovy.maven.archetypes \
  -DarchetypeArtifactId=gmaven-archetype-basic \
  -DarchetypeVersion=1.0-rc-3

Define value for groupId: : net.olioinfo
Define value for artifactId: : configatron-groovy
Define value for version:  1.0-SNAPSHOT: : 0.1
Define value for package:  net.olioinfo: : net.olioinfo.configatron
Confirm properties configuration:
name: Example Project
groupId: net.olioinfo
artifactId: configatron-groovy
version: 0.1
package: net.olioinfo.configatron
 Y: : Y

Double-click on the video player to open on YouTube.

Maven – The basic build phases

These notes are summarized from the main Maven site, at ‘Introduction to the Build Lifecycle‘.

These notes assume a standard Maven installation.

The basic build phases (think Ant ‘targets’) for Maven builds are the following:

  • validate – validate the project is correct and all necessary information is available
  • compile – compile the source code of the project
  • test – test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
  • package – take the compiled code and package it in its distributable format, such as a JAR.
  • integration-test – process and deploy the package if necessary into an environment where integration tests can be run
  • verify – run any checks to verify the package is valid and meets quality criteria
  • install – install the package into the local repository, for use as a dependency in other projects locally
  • deploy – done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

For a complete list of the build phases, refer to the Lifecycle Reference.

To run any phase, specify:

mvn <phase>

For example to compile a project:

mvn compile

Java – Resources and Properties

This article is part of the Java – From the ground up series. This article is mostly summarized from here.

Resource files

Roughly speaking, any file that a Java application needs that isn’t a class file can be thought of as a resource  file.

At its simplest, Java applies the same rules for loading a resource as it does for loading a class – that is uses the Java classpath and class loaders. This typically requires that the resource be included in a JAR file or a WAR file for a web application.

Resource bundles and internationalization (i18n)

Resources are used for a lot things – internationalization being one of them.  The basic idea to is to collect a group of settings that relate to these features:

  • Locales
  • Number formats
  • Data and time
  • Collation order
  • Message formats
  • Messages

The ‘bundle’ notion comes in when the settings for these features are goupred into one or more files. This file or group of files is termed a resource bundle.  Each locale that is supported must have its own resource bundle. A specific naming convention is used for all the files associated with a given locale. Refer to standard documentation for a description of the naming convention and search conventions.

Properties files

.properties files are used in two basic ways:

  • To store strings for internationalization support
  • To store general application-level settings

The second usage for .properties files – application-level settings -  typically doesn’t exploit the locale support described above, even though it is still used ‘under the covers’ to load the .properties file.

There are several aspects of the plain text format for properties files to watch out for:

  • Entries consist of  key/value pairs
  • Both keys and values are treated as Strings
  • The naming of keys uses a ‘flat’ namespace – all keys exist in the same namespace
  • All keys within a namespace must be unique

That leads to properties files that look similar to the following:

first.property=1
second.property=2
apropertylist.entry.1=a
apropertylist.entry.2=b

An alternative that removes some of these limitations is to use an XML format for properties files.

Java – log4j configuration

Log4j is a widely-used Java logging package.

How does Log4j find configuration information?

From the Log4j Manual – Default initialization procedure

The log4j library does not make any assumptions about its environment. In particular, there are no default log4j appenders. Under certain well-defined circumstances however, the static inializer of the Logger class will attempt to automatically configure log4j. The Java language guarantees that the static initializer of a class is called once and only once during the loading of a class into memory. It is important to remember that different classloaders may load distinct copies of the same class. These copies of the same class are considered as totally unrelated by the JVM.

The default initialization is very useful in environments where the exact entry point to the application depends on the runtime environment. For example, the same application can be used as a stand-alone application, as an applet, or as a servlet under the control of a web-server.

The exact default initialization algorithm is defined as follows:

  1. Setting the log4j.defaultInitOverride system property to any other value then “false” will cause log4j to skip the default initialization procedure (this procedure).
  2. Set the resource string variable to the value of the log4j.configuration system property. The preferred way to specify the default initialization file is through the log4j.configuration system property. In case the system property log4j.configuration is not defined, then set the string variable resource to its default value “log4j.properties”.
  3. Attempt to convert the resource variable to a URL.
  4. If the resource variable cannot be converted to a URL, for example due to a MalformedURLException, then search for the resource from the classpath by calling org.apache.log4j.helpers.Loader.getResource(resource, Logger.class) which returns a URL. Note that the string “log4j.properties” constitutes a malformed URL. See Loader.getResource(java.lang.String) for the list of searched locations.
  5. If no URL could not be found, abort default initialization. Otherwise, configure log4j from the URL. The PropertyConfigurator will be used to parse the URL to configure log4j unless the URL ends with the “.xml” extension, in which case the DOMConfigurator will be used. You can optionaly specify a custom configurator. The value of the log4j.configuratorClass system property is taken as the fully qualified class name of your custom configurator. The custom configurator you specify must implement the Configurator interface.

From the Log4j Manual – Default initialization under Tomcat

The default log4j initialization is particularly useful in web-server environments. Under Tomcat 3.x and 4.x, you should place the log4j.properties under the WEB-INF/classes directory of your web-applications. Log4j will find the properties file and initialize itself. This is easy to do and it works. You can also choose to set the system property log4j.configuration before starting Tomcat. For Tomcat 3.x The TOMCAT_OPTS environment variable is used to set command line options. For Tomcat 4.0, set the CATALINA_OPTS environment variable instead of TOMCAT_OPTS. Example 1

The Unix shell command

   export TOMCAT_OPTS="-Dlog4j.configuration=foobar.txt"

tells log4j to use the file foobar.txt as the default configuration file. This file should be place under the WEB-INF/classes directory of your web-application. The file will be read using the PropertyConfigurator. Each web-application will use a different default configuration file because each file is relative to a web-application.

Example 2

The Unix shell command

   export TOMCAT_OPTS="-Dlog4j.debug -Dlog4j.configuration=foobar.xml"

tells log4j to output log4j-internal debugging information and to use the file foobar.xml as the default configuration file. This file should be place under the WEB-INF/classes directory of your web-application. Since the file ends with a .xml extension, it will read using the DOMConfigurator. Each web-application will use a different default configuration file because each file is relative to a web-application.

Example 3

The Windows shell command

   set TOMCAT_OPTS=-Dlog4j.configuration=foobar.lcf -Dlog4j.configuratorClass=com.foo.BarConfigurator

tells log4j to use the file foobar.lcf as the default configuration file. This file should be place under the WEB-INF/classes directory of your web-application. Due to the definition of the log4j.configuratorClass system property, the file will be read using the com.foo.BarConfigurator custom configurator. Each web-application will use a different default configuration file because each file is relative to a web-application.

Example 4

The Windows shell command

   set TOMCAT_OPTS=-Dlog4j.configuration=file:/c:/foobar.lcf

tells log4j to use the file c:\foobar.lcf as the default configuration file. The configuration file is fully specified by the URL file:/c:/foobar.lcf. Thus, the same configuration file will be used for all web-applications.

Different web-applications will load the log4j classes through their respective classloaderss. Thus, each image of the log4j environment will act independetly and without any mutual synchronization. For example, FileAppenders defined exactly the same way in multiple web-application configurations will all attempt to write the same file. The results are likely to be less than satisfactory. You must make sure that log4j configurations of different web-applications do not use the same underlying system resource.

Initialization servlet

It is also possible to use a special servlet for log4j initialization. Here is an example,

package com.foo;

import org.apache.log4j.PropertyConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.IOException;

public class Log4jInit extends HttpServlet {

  public
  void init() {
    String prefix =  getServletContext().getRealPath("/");
    String file = getInitParameter("log4j-init-file");
    // if the log4j-init-file is not set, then no point in trying
    if(file != null) {
      PropertyConfigurator.configure(prefix+file);
    }
  }

  public
  void doGet(HttpServletRequest req, HttpServletResponse res) {
  }
}

Define the following servlet in the web.xml file for your web-application.

  <servlet>
    <servlet-name>log4j-init</servlet-name>
    <servlet-class>com.foo.Log4jInit</servlet-class>

    <init-param>
      <param-name>log4j-init-file</param-name>
      <param-value>WEB-INF/classes/log4j.lcf</param-value>
    </init-param>

    <load-on-startup>1</load-on-startup>
  </servlet>

Writing an initialization servlet is the most flexible way for initializing log4j. There are no constraints on the code you can place in the init() method of the servlet.

Java and Classpath

This article is part of the Java – From the ground up series. This article is mostly summarized from here.

Classpath Basics

The Java classpath is the path that Java JVM searches to find classes.

Conceptually, when the JVM is asked to load a class:

  • It generates the qualified name of the class – the class package + the class name + ‘.class’
  • It changes any ‘.’ in the package name to the file system separator (‘\’ on Windows, ‘/’ on most other OSes)
  • It prepends each element of the classpath in turn starting at the beginning to the qualified name of the class
  • The first match becomes the class the JVM loads

Classpath and JARs

From the point of view of the classpath, each JAR file is treated as a separate directory. So, every JAR used in a Java application needs to be included separately in the classpath.

Specifying the Classpath

The classpath setting is examined in the following order. The first classpath found is used.

  • The Java compiler (‘javac’) or Java VM (‘java’) command-line option ‘-cp’ or ‘-classpath’
  • The environment setting ‘CLASSPATH’

What’s included automatically in the Classpath

The Java compiler (‘javac’) always includes the following implicitly in the search path:

  • The current directory ‘.’ – this is always searched first
  • The directories ‘./jre/lib’ and ‘.jre/lib/ext’ in order (for JARs)

The Java Virtual Machine (‘java’) always includes the following implicitly in the classpath:

  • The directories ‘./jre/lib’ and ‘.jre/lib/ext’ in order (for JARs)

Note that the JVM does not include ‘.’ in the classpath implicitly, unlike the Java compiler. It needs to be included explicitly.

JARs file in the ./jre/lib/ext directory

The simple answer is don’t. Any recommendation to bypass the classpath mechanism by placing JAR files in the  ./jre/lib/ext directory is to be ignored. There are two main reasons:

  • JAR files in the ./jre/lib/ext are loaded before any application-level JARs and classes so do not and cannot depend on (other) application-level JARs
  • People forget – that files have been put there.

Java – Class loaders

This article is part of the Java – From the ground up series. This article is mostly summarized from here and here.

Java Class loaders and why they’re important.

Every class that’s loaded into a JVM is loaded by a class loader.  So, class loaders are significant, and knowing about them is important.

The most important thing from the point of any class, is that, once it’s been loaded, the JVM assigns it a unique identifier based on the combination of the specific class loader and the class itself. So, the golden rule::

  • Two copies of the same class loaded by separate class loaders are considered distinct by the JVM.

Class loader hierarchy

Class loaders exist in a strict hierarchy:

  • The bootstrap class loader
  • The extension class loader
  • The system class loader (a.k.a. the application class loader)
  • Specific class loaders in an application

The class  loader that is most relevant at the application level is the system class loader.

  • If specific application-level class loaders are not specified, all classes in an application context are loaded by the system classloader.
  • If no parent is specified for a given class loader, the system class loader is implied as the parent

Creating a class loader

The basic design rule for a class loader is simple:

  • Extend the  system class loader
  • Let the system class loader try to load the class first (this is usually automatic)
  • Override the findClass(String className) method

Threads and class loaders

Every thread has a reference to a class loader, known as its context class loader.

  • The main thread starts off with the system class loader
  • When a subsequent thread is created, its context class loader is set to the context class loader of the creating thread unless overridden.

Java – From the ground up

This is the starting point for a set of Java-related topics. These are mostly topics that need clarifications in a lot of cases.

Java and Classpath

Java and Class loaders

Java – Resources and Properties

References for this series ‘Java – From the ground up’

WordPress Themes