This Tip Of The Day (TOTD) is a refresh of Embeddable GlassFish in Action - Servlet in a Maven Project.

GlassFish v3 runs easily in embedded mode - no download, installation, or configuration - every thing done programmatically within a JVM. This blog shows how to deploy a simple Servlet using these APIs and then write a simple test to invoke it - all within the same VM.

Lets get started!

  1. Lets create our Maven project:
    mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes \ -DgroupId=org.glassfish.embedded.samples -DartifactId=webtier2
  2. Add the following , , and to the generated "pom.xml:
    glassfish-repository Repository for Glassfish . . . . . . org.glassfish.extras glassfish-embedded-all 3.0 org.apache.maven.plugins maven-compiler-plugin 2.0.2 1.5 1.5
    Read Setting the Class Path for more discussions on the different JAR files that are available. The version may be changed form "3.0" to "3.1-SNAPSHOT" to pick the latest bug fixes and improvements.
  3. Change the generated "src/main/java/org/glassfish/embedded/samples/" to:
    package org.glassfish.embedded.samples; import; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Hello world! */ @WebServlet(name="app", urlPatterns={"/app"}) public class App extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("Hello Duke"); } } This is using "@WebServlet" annotation, a new feature in Servlets 3.0, to mark a POJO as a Servlet. Notice the servlet is hosted at "/app" URL. No "web.xml" will be required in this case.
  4. Edit the generated "src/test/java/org/glassfish/embedded/samples/" and add the following method:
    public void testServlet() throws IOException, LifecycleException { // Build a server Server.Builder builder = new Server.Builder("server"); Server server =; // Specify the port server.createPort(8080); // Add the Web container server.addContainer(ContainerBuilder.Type.web); // Create the WAR file ScatteredArchive.Builder saBuilder = new ScatteredArchive.Builder("test", Collections.singleton(new File("target/classes").toURI().toURL())); ScatteredArchive archive = saBuilder.buildWar(); // Deploy the WAR file EmbeddedDeployer deployer = server.getDeployer(); deployer.deploy(archive, null); // Read the response from the servlet hosted at "/app" URL url = new URL("http://localhost:8080/test/app"); BufferedReader br = new BufferedReader( new InputStreamReader( url.openConnection().getInputStream())); // ... and assert assertEquals("Hello Duke", br.readLine()); } This method is well commented and where all the magic is happening.

    The updated import statements look like:
    import; import; import; import; import; import java.util.Collections; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.glassfish.api.deployment.DeployCommandParamete rs; import org.glassfish.api.embedded.ContainerBuilder; import org.glassfish.api.embedded.EmbeddedDeployer; import org.glassfish.api.embedded.LifecycleException; import org.glassfish.api.embedded.ScatteredArchive; import org.glassfish.api.embedded.Server;
  5. And now fire the following command:
    mvn test
    and see the output as:

    Running org.glassfish.embedded.samples.AppTest Apr 30, 2010 10:49:55 AM com.sun.enterprise.v3.server.AppServerStartup run INFO: GlassFish v3 (74.2) startup time : Embedded(498ms) startup services(433ms) total(931ms) Apr 30, 2010 10:49:55 AM com.sun.enterprise.transaction.JavaEETransactionMa nagerSimplified initDelegates INFO: Using com.sun.enterprise.transaction.jts.JavaEETransacti onManagerJTSDelegate as the delegate Apr 30, 2010 10:49:55 AM org.glassfish.admin.mbeanserver.JMXStartupService$ JMXConnectorsStarterThread run INFO: JMXStartupService: JMXConnector system is disabled, skipping. Apr 30, 2010 10:49:55 AM AppServerStartup run INFO: [Thread[GlassFish Kernel Main Thread,5,main]] started Apr 30, 2010 10:49:55 AM org.hibernate.validator.util.Version INFO: Hibernate Validator null Apr 30, 2010 10:49:55 AM org.hibernate.validator.engine.resolver.DefaultTra versableResolver detectJPA INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATravers ableResolver. Apr 30, 2010 10:49:56 AM$2 $1 onReady INFO: Grizzly Framework 1.9.18-k started in: 154ms listening on port 8080 Apr 30, 2010 10:50:00 AM com.sun.common.util.logging.LoggingConfigImpl openPropFile INFO: Cannot read file. Apr 30, 2010 10:50:00 AM com.sun.enterprise.web.WebContainer createHttpListener INFO: Created HTTP listener embedded-listener on port 8080 Apr 30, 2010 10:50:00 AM com.sun.enterprise.web.WebContainer configureHttpServiceProperties WARNING: pewebcontainer.invalid_http_service_property Apr 30, 2010 10:50:00 AM com.sun.enterprise.web.WebContainer createHosts INFO: Created virtual server server Apr 30, 2010 10:50:00 AM com.sun.enterprise.web.WebContainer loadSystemDefaultWebModules INFO: Virtual server server loaded system default web module Apr 30, 2010 10:50:02 AM INFO: security.secmgroff Apr 30, 2010 10:50:03 AM checkCertificateDates SEVERE: java_security.expired_certificate Apr 30, 2010 10:50:03 AM onInitialization INFO: Security startup service called Apr 30, 2010 10:50:03 AM loadPolicy INFO: policy.loading Apr 30, 2010 10:50:03 AM doInstantiate INFO: Realm admin-realm of classtype alm successfully created. Apr 30, 2010 10:50:03 AM doInstantiate INFO: Realm file of classtype alm successfully created. Apr 30, 2010 10:50:03 AM doInstantiate INFO: Realm certificate of classtype .CertificateRealm successfully created. Apr 30, 2010 10:50:03 AM onInitialization INFO: Security service(s) started successfully.... classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/) SharedSecrets.getJavaNetAccess() Loader$7@71e13a2c Apr 30, 2010 10:50:03 AM com.sun.enterprise.web.WebApplication start INFO: Loading application test at /test Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 9.845 sec Results : Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
    The key messages in the log are highlighted in bold.

    As you can see embedded GlassFish started in less than a second ... neat! It also shows a message that HTTP listener is starting on port 8080. And finally the 2 tests passed - one is the default one generated by Maven and other is the new one that we added!
A future blog will show how to create JDBC resource using these APIs and use the JPA 2 APIs to query an in-memory database.

Alternatively, you can also use the Maven plug-in or EJB 3.1 Embeddable API. Always refer to the GlassFish v3 Embedded Server Guide for the definitive documentation. The latest javadocs are available here.

How are you using embeddable GlassFish ?

Technorati: totd glassfish v3 javaee embedded servlet

Read More about [TOTD #132: Servlets 3.0 in Embedded GlassFish Reloaded - lightweight Java EE 6...