Java EE 6 Development using the Maven Embedded GlassFish Plugin
September 20th, 2011 by Micha KopsToday 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.
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.
Contents
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
- 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
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 ..
Tutorial Sources
I have put the source from this tutorial on my Bitbucket repository – download it there or check it out using Mercurial:
hg clone https://bitbucket.org/hascode/maven-embedded-glassfish-tutorial
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>
Resources
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>
Tags: deployment, ejb, embedded, Enterprise, glassfish, javaee, jee, maven, servlet
September 21st, 2011 at 11:40 am
Excellent Article!
Do you care if I make a translation in my blog? Quoting the source, of course.
September 24th, 2011 at 7:54 am
looks rly good! going to try
October 30th, 2011 at 8:34 pm
Hi Micha,
Perfect!
This is what i was looking for.
This works fine.
The problem I faced was -
When I run mvn glassfish:run
my build gets failed with below error -
[ERROR] No plugin found for prefix ‘glassfish’ in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo]
available from the repositories [local (C:\maven\local_repo), maven.java.net (http://download.java.net/maven/2), glassfish-repository (http
://download.java.net/maven/glassfish), central (http://repo1.maven.org/maven2) -> [Help 1]
But when I do mvn clean install, it installs and starts the glassfish automatically.
June 26th, 2012 at 3:25 pm
Hi and thanks for your blog,
I’ve got a problem when i try to run embedded plugin on Windows XP 2002 :
INFO: WEB0172: Virtual server [server] loaded default web module []
classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
26 juin 2012 17:09:47 org.glassfish.api.ActionReport failure
SEVERE: Exception while loading the app
SharedSecrets.getJavaNetAccess()=null
classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
SharedSecrets.getJavaNetAccess()=null
26 juin 2012 17:09:47 org.glassfish.deployment.admin.DeployCommand execute
SEVERE: Exception while loading the app : org.glassfish.web.plugin.common.WebModuleConfig
Throwable occurred: java.lang.ClassNotFoundException: org.glassfish.web.plugin.common.WebModuleConfig
same project works fine on macos X (SharedSecrets.getJavaNetAccess() is not null)
July 18th, 2012 at 9:52 am
Hi,
Fabien, did you solve your problem?
regards.
August 30th, 2012 at 1:05 pm
[...] http://www.hascode.com/2011/09/java-ee-6-development-using-the-maven-embedded-glassfish-plugin/ [...]
March 24th, 2014 at 6:50 am
Hello,
Thanks for a nice tutorial!
I’ve created a dynamic web application using maven through command line as explained here: http://docs.oracle.com/cd/E19226-01/820-7627/giqdq/
When I do mvn embedded-glassfish:run, I’m getting a message telling this:
Mar 24, 2014 12:01:43 PM PluginUtil doUndeploy
INFO: Deployer = com.sun.enterprise.admin.cli.embeddable.DeployerImpl@1a3af98
PlainTextActionReporterFAILUREApplication RestHelloApp is not deployed on this
arget [server]Mar 24, 2014 12:01:43 PM PluginUtil doUndeploy
INFO: Undeployed RestHelloApp
[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————
[INFO] Total time: 02:46 min
[INFO] Finished at: 2014-03-24T12:01:43+05:30
[INFO] Final Memory: 15M/37M
[INFO] ————————————————————————
Could you please explain why the application is not getting deployed and why is the PlainTextActionReporter Failure occurs?
Thanks