Today we’re going to take a look at the Maven Embedded GlassFish Plugin and how it allows us quick creation of GlassFish server instances in no time and Java EE 6 application deployment.

logo
Figure 1. GlassFish + Maven

With a few lines of configuration in your Maven’s pom.xml we’ve got a running GlassFish instance and are able to redeploy our application fast by pressing enter in our console.

In the following tutorial we’re going to build a Java EE 6 Web Application with a stateless session bean and a web servlet and finally deploy – and redeploy the application using the Maven GlassFish Plugin.

Prerequisites

We just need Maven and a JDK …

New project using the Java EE Archetype

In the first step we’re going to create a new mavenized project using an Java EE maven archetype …

  • We’re creating a new Maven project using the archetype org.codehaus.mojo.archetypes:webapp-javaee6:1.5
    new javaee maven project

  • If you’re encountering Maven errors due to the new Sonatype m2eclipse plugin, take a look at the troubleshooting section :)

  • Now add the dependency for the maven-embedded-glassfish-plugin to your pom.xml

    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>maven-embedded-glassfish-plugin</artifactId>
      <version>3.1.1</version>
      <type>maven-plugin</type>
    </dependency>
  • Finally we’re adding some configuration for our embedded GlassFish instance to run on port 8080 and using the project’s name as context root .. my final pom.xml looks like this one now

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    
    	<groupId>com.hascode.tutorial.jee</groupId>
    	<artifactId>embedded-glassfish-tutorial</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>war</packaging>
    	<name>embedded-glassfish-tutorial</name>
    	<url>https://www.hascode.com</url>
    	<description>hasCode.com Maven Embedded Glassfish Tutorial</description>
    
    	<properties>
    		<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>javax</groupId>
    			<artifactId>javaee-web-api</artifactId>
    			<version>6.0</version>
    			<scope>provided</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.glassfish</groupId>
    			<artifactId>maven-embedded-glassfish-plugin</artifactId>
    			<version>3.1.1</version>
    			<type>maven-plugin</type>
    		</dependency>
    	</dependencies>
    
    	<repositories>
    		<repository>
    			<id>maven2-repository.dev.java.net</id>
    			<name>Java.net Repository for Maven</name>
    			<url>http://download.java.net/maven/2</url>
    		</repository>
    		<repository>
    			<id>glassfish-repository</id>
    			<name>Java.net Repository for Glassfish</name>
    			<url>http://download.java.net/maven/glassfish</url>
    		</repository>
    	</repositories>
    
    	<pluginRepositories>
    		<pluginRepository>
    			<id>maven.java.net</id>
    			<name>Java.net Maven2 Repository</name>
    			<url>http://download.java.net/maven/2</url>
    		</pluginRepository>
    		<pluginRepository>
    			<id>glassfish-repository</id>
    			<name>Java.net Repository for Glassfish</name>
    			<url>http://download.java.net/maven/glassfish</url>
    		</pluginRepository>
    	</pluginRepositories>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>2.3.2</version>
    				<configuration>
    					<source>1.6</source>
    					<target>1.6</target>
    					<compilerArguments>
    						<endorseddirs>${endorsed.dir}</endorseddirs>
    					</compilerArguments>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-war-plugin</artifactId>
    				<version>2.1.1</version>
    				<configuration>
    					<failOnMissingWebXml>false</failOnMissingWebXml>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-dependency-plugin</artifactId>
    				<version>2.1</version>
    				<executions>
    					<execution>
    						<phase>validate</phase>
    						<goals>
    							<goal>copy</goal>
    						</goals>
    						<configuration>
    							<outputDirectory>${endorsed.dir}</outputDirectory>
    							<silent>true</silent>
    							<artifactItems>
    								<artifactItem>
    									<groupId>javax</groupId>
    									<artifactId>javaee-endorsed-api</artifactId>
    									<version>6.0</version>
    									<type>jar</type>
    								</artifactItem>
    							</artifactItems>
    						</configuration>
    					</execution>
    				</executions>
    			</plugin>
    			<plugin>
    				<groupId>org.glassfish</groupId>
    				<artifactId>maven-embedded-glassfish-plugin</artifactId>
    				<version>3.1.1</version>
    				<configuration>
    					<goalPrefix>glassfish</goalPrefix>
    					<app>target/${artifactId}-${version}.${packaging}</app>
    					<port>8080</port>
    					<contextRoot>${name}</contextRoot>
    					<name>${name}</name>
    				</configuration>
    				<executions>
    					<execution>
    						<phase>install</phase>
    						<goals>
    							<goal>run</goal>
    						</goals>
    					</execution>
    				</executions>
    			</plugin>
    		</plugins>
    	</build>
    </project>

Creating an Enterprise Web Application

Now that we’ve got all dependencies we need and a valid maven project we’re going to build a simple Java EE Web Application …

  • First we’re going to create a stateless session bean that simply prints a date ..we’re using the @Stateless annotation to create the stateless session bean named MyServiceEJB

    package com.hascode.tutorial.jee;
    
    import java.util.Date;
    
    import javax.ejb.Stateless;
    
    @Stateless
    public class MyServiceEJB {
    	public String printDate() {
    		return "The date is: " + new Date().toString();
    	}
    }

    __

  • In the next step, we’re creating a simple servlet that gets the stateless EJB injected and prints out some simple information: DemoServlet

    package com.hascode.tutorial.jee;
    
    import java.io.IOException;
    
    import javax.ejb.EJB;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet(name = "demoServlet", urlPatterns = "/demo-servlet")
    public class DemoServlet extends HttpServlet {
    	@EJB
    	private MyServiceEJB myServiceEJB;
    
    	@Override
    	protected void doGet(final HttpServletRequest req,
    			final HttpServletResponse res) throws ServletException, IOException {
    		res.getWriter().append(myServiceEJB.printDate());
    	}
    
    }

Running the App

Now there is nothing much to do now .. building the app and using the maven glassfish plugin to start a new server instance and deploy the application

  • Build and package the application using

    mvn clean package
  • Run GlassFish using

    mvn glassfish:run
    or
    mvn org.glassfish:maven-embedded-glassfish-plugin:3.1.1:run
  • The console displays some useful information about the starting GlassFish instance e.g. deployed EJBs or Servlets or JNDI names created.. e.g.:

    INFO: Portable JNDI names for EJB MyServiceEJB : [java:global/embedded-glassfish-tutorial/MyServiceEJB!com.hascode.tutorial.jee.MyServiceEJB, java:global/embedded-glassfish-tutorial/MyServiceEJB]
    Sep 20, 2011 8:19:00 PM com.sun.enterprise.web.WebApplication start
    INFO: WEB0671: Loading application [embedded-glassfish-tutorial] at [/embedded-glassfish-tutorial]
  • Finally you should get the following output

    INFO: Deployed embedded-glassfish-tutorial
    Hit ENTER to redeploy, X to exit
  • By now you should be able to call the demo servlet by pointing your browser to the URL http://localhost:8080/embedded-glassfish-tutorial/demo-servlet

    demo servlet 1
    Figure 2. Demo Servlet Output - Run 1

Altering and Redeployment

Now to demonstrate the nifty redeployment feature of the maven-embedded-glassfish-plugin we’re going to alter our original code ..

  • We’re changing the string returned by our stateless session bean

    return "The date is at the moment: " + new Date().toString();
  • Now run..

    mvn package
  • Go into your console still opened from the previous mvn glassfish:run and hit enter – you should see the following output

    Sep 20, 2011 8:40:53 PM PluginUtil doUndeploy
    INFO: Deployer = com.sun.enterprise.admin.cli.embeddable.DeployerImpl@104ca54
    classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
    SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@1bf8de1
    PlainTextActionReporterSUCCESSNo monitoring data to report.
    Sep 20, 2011 8:40:53 PM PluginUtil doUndeploy
    INFO: Undeployed embedded-glassfish-tutorial
    classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
    SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@1bf8de1
    Sep 20, 2011 8:40:54 PM com.sun.ejb.containers.BaseContainer initializeHome
    INFO: Portable JNDI names for EJB MyServiceEJB : [java:global/embedded-glassfish-tutorial/MyServiceEJB!com.hascode.tutorial.jee.MyServiceEJB, java:global/embedded-glassfish-tutorial/MyServiceEJB]
    Sep 20, 2011 8:40:54 PM com.sun.enterprise.web.WebApplication start
    INFO: WEB0671: Loading application [embedded-glassfish-tutorial] at [/embedded-glassfish-tutorial]
    Sep 20, 2011 8:40:54 PM org.glassfish.deployment.admin.DeployCommand execute
    INFO: embedded-glassfish-tutorial was successfully deployed in 262 milliseconds.
    PlainTextActionReporterSUCCESSDescription: deploy AdminCommandApplication deployed with name embedded-glassfish-tutorial.
        [name=embedded-glassfish-tutorial
    Hit ENTER to redeploy, X to exitSep 20, 2011 8:40:54 PM PluginUtil doDeploy
    INFO: Deployed embedded-glassfish-tutorial
  • Now refresh your browser pointing to http://localhost:8080/embedded-glassfish-tutorial/demo-servlet and notice that the output has changed ..

    demo servlet 2
    Figure 3. Demo Servlet Output - Run 2

Tutorial Sources

I have put the source from this tutorial on my GitHub repository – download it there or check it out using Git:

git clone https://github.com/hascode/maven-embedded-glassfish-tutorial.git

Troubleshooting

  • Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-dependency-plugin:2.1:copy (execution: default, phase: validate)” – It’s the m2eclipse plugin .. why does this error occur? They’re explaining it in this article .. for now add the following code to your pom.xml and update your project configuration

    <pluginManagement>
      <plugins>
        <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
        <plugin>
          <groupId>org.eclipse.m2e</groupId>
          <artifactId>lifecycle-mapping</artifactId>
          <version>1.0.0</version>
          <configuration>
            <lifecycleMappingMetadata>
              <pluginExecutions>
                <pluginExecution>
                  <pluginExecutionFilter>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <versionRange>[2.1,)</versionRange>
                    <goals>
                      <goal>copy</goal>
                    </goals>
                  </pluginExecutionFilter>
                  <action>
                    <ignore></ignore>
                  </action>
                </pluginExecution>
              </pluginExecutions>
            </lifecycleMappingMetadata>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>