Embedded Server – Tomcat 7

What is an Embedded Server?

Traditionally, java web applications have been seen as WAR files deployed on servlet containers and application servers.
Simultaneously another school of thought advocates deploying a server with an application; pioneered by Jetty. Tomcat too comes in this flavour – as embedded tomcat. In an embedded server application, the application is deployed and run as a JAR. This JAR file launches a main() method which in turn starts the server and deploys itself on it. With such an application, we eliminate dependency on having a server. Any machine that can run java, can act as a server.What advantages such a server have? None. The only advantage we have is that we can use it to develop small applications. Applications that can be run on machine that have just a JRE. For example, say in my uncle’s medicine shop. There is no setup cost involved – other than the machine itself.

In this article

In this article, we shall discuss about
  1. Softwares involved
  2. Project setup using maven
  3. Embedding tomcat server

Softwares involved

  1. JDK – preferably the latest
  2. Maven – preferably the latest
  3. An editor to write java classes.

You should also be connected to internet – to allow maven download its dependencies – and I bet there are many.

Project setup using Maven

We shall be creating a web archieve project – inline with J2EE specification. But we shall also be using maven. So the folder structure will follow maven standard, and not the structure that we see in eclipse projects.
Create the following depicted folder structure
  • The name of project is ‘SampleProject’.
  • There is an src folder that houses 2 folders – ‘main’ and ‘test’.
  • The ‘test’ folder is used to write test scripts. We won’t be doing that.
  • The ‘src’ folder is where we keep java source and also the web appllication files. So it has 2 children – ‘java’ for source code and ‘webapp’ for the web application resources. See the ‘WEB-INF’ folder that houses web.xml file.
Next create a pom.xml file in ‘SampleProject’ folder. And write the following in it.
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.heroku.sample</groupId>
<artifactId>embeddedTomcatSample</artifactId>
<version>1.0-SNAPSHOT</version>
<name>embeddedTomcatSample Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>7.0.22</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>7.0.22</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>7.0.22</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>7.0.22</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>7.0.22</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jsp-api</artifactId>
<version>7.0.22</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
</dependencies>
<build>
<finalName>embeddedTomcatSample</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>com.ego.apps.Launch</mainClass>
<name>webapp</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

Note – the dependencies section list out the JARs needed for embedded tomcat.

Now we need to tell maven to download these dependencies – so that we can continue with our application. Navigate to the SampleProject folder and issue command

mvn install

This would install all the dependencies required.

Now, go ahead and create a servlet. We created following

package com.ego.apps.servlets;

import java.io.IOException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
try
    {
    response.getOutputStream().print("Hello World!");
    }
catch (IOException e)
    {
    }
}
}

And edit the web.xml in WEB-INF as

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>

<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>com.ego.apps.servlets.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

</web-app>

This completes our web application setup by issuing final command

mvn clean install

Embedding tomcat server

We have our web application ready. It can be archieved as a WAR and deployed on any server.
But no, we are smart and will package our server with out application. So create a java file as given below
package com.ego.apps;

import java.io.File;

import org.apache.catalina.startup.Tomcat;
import org.apache.log4j.Logger;

public class Launch {
public static void main(String[] args) throws Exception {
Logger logger = Logger.getLogger(Launch.class);
String webappDirLocation = "src/main/webapp/";
Tomcat tomcat = new Tomcat();

// Look for that variable and default to 8080 if it isn't there.
String webPort = System.getenv("PORT");
if (webPort == null || webPort.isEmpty()) {
webPort = "8080";
}
logger.info("Application port set to: " + webPort);
tomcat.setPort(Integer.valueOf(webPort));

tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
logger.info("configuring app with basedir: "
+ new File("./" + webappDirLocation).getAbsolutePath());

tomcat.start();
logger.info("Application started.");
tomcat.getServer().await();
}
}
 If you go through the main() method of the class, you will figure out that it instantiates tomcat with a port number to run upon.
Tomcat tomcat = new Tomcat();</pre>
tomcat.setPort(Integer.valueOf(webPort));

The command above instantiated tomcat and sets the port to listen to as 8080.

Now we need to guide tomcat to deploy our application.  This is done as

tomcat.addWebapp("/", new File("src/main/webapp/").getAbsolutePath());

Once web application is added to tomcat, we can start it. It runs as a thread and awaits requests. The command is

tomcat.start();
tomcat.getServer().await();

And ta-da.

Now its time to compile and run our application.
First we clean maven directory, compile the code and package it as

mvn clean install

The packaging creates target directory where all the temporary artifacts are kept. The war file is kept here as “embeddedTomcatSample” because this what we mentioned in POM dependencies section. This JAR is run using the batch file generated in target\bin. Run it as

target\bin\webapp.bat

This would start the tomcat server for us.

Strings and String literals in String Literal Pool

A lot of times I have been asked questions to count the number of string objects created in a statement. Yes, typically by product companies. So it triggered me to actually write an article on it.

Let us discuss on the following topics then

  • String is immutable
  • String pool
  • String literal and garbage collection

String is immutable?

Strings are immutable objects. 

Yes, once created, they cannot be change. Although we can perform operations on it to create new string objects.

 
String str = "a" + "b";

In the statement above, we actually create string object “a”, then string object “b” and then append them to create new string object “c”. We do not alter the original strings “a” and “b”.
Same is the case when we write

 String s1 = "a";
String s2 = s1.concat("b");

String object “a” is created. String object “b” is created and concatenated to “a”. Oh no, String object “a” and “b” are added and new String object “ab” is created. The concat() is hence a misnomer. But one thing worth noting about the concat() according to javadoc is

If the length of the argument string is 0, then this String object is returned. Otherwise, a new String object is created, representing a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string.

Fairly simple but worth noting.

 String literal pool

String literal pool is a collection of references to String objects.

But the String objects are themselves created on heap, just like other objects. And the String literal pool references are maintained by the JVM (say in a table).

String literals and String pool

Now since the String objects are immutable, it is safe for multiple references to same literal actually share the same object.

 String s1 = "harsh";
String s2 = "harsh";

The code above seems to create 2 String objects, with literal as “harsh”. But in JVM, both the references s1 and s2 point to the same String object.
How do we test that?

System.out.println("Equals method: " + s1.equals(s2));
System.out.println("==: " + (s1 == s2));

This should explain you what I am trying to say.

What happens behind the scenes is that the string literals are noted down separately by the compiler. When the classloader loads the class, goes through the literal table. When it finds a literal, it searches through the list of String pool references to see if the equivalent String already exists on heap. If one already exists, all the references in class to this String literal are replaced with the reference to the String object on heap (pointed to by the String literal table). If none exists, then a new object is created on heap and then its reference is created on String literal pool table. So any subsequent references to this literal are automatically mapped to the existing String object on heap.

The ‘new’ operator and String literal pool

When it comes to the ‘new’ operator, it forces the JVM to create a new String object on the String literal pool. It has no connection whatsoever with the objects on String literal pool.

A ‘new’ operator creates and points to a new String object on heap.

Hence, do not think ‘String literal pool’ when you encounter ‘new’ operator.

Literal mathematics through constant operations

What about the String created through literal mathematics?
String s1 = "ab" + "c";
String s2 = "a" + "bc";

The above operation also creates a single literal on string pool, and both the references point to it. How? Because compiler can calculate this at compile time, that we are doing string literal constant mathematics.

Literal mathematics through objects

String s1 = "a";
String s2 = s1 + "bc";
String s3 = "a" + "bc";
In statements above, s2 and s3 do not point to the same literal.
i.e. when we perform some mathematics through references, compiler isn’t able to identify the resultant string at compile time, and hence does not make an entry for the literal pool.
String object referenced by s1 and s3 go on the literal pool, but not the one referenced by s2 as it is created at runtime.

String literal garbage collection

An object is eligible for garbage collection when it is no longer referenced.

But our String literals on the literal pool are always referenced by the literal pool. So they are never eligible for garbage collection. They are always accessible through String interns.
But the objects created by ‘new’ operator are eligible if they are no longer referenced – as they are never referred to by the pool.

Navigating from calendar activity by clicking in Oracle ADF – Techartifact

af:calendar component in ADF is widely used.It is same as Google calendar we used. In calendar we are having different activities .We are having different calendar facet inside the calendar component i. e activitydetail, activityDelete, activityHover, activityContextMenu, create , contextMenu.

If you look down the property of calendar component inside property pallet. you will not find action or actionListener property instead of you will get
calendarActivity, calendarListener etc.

Now my requirment is to clicking on the calendar component , it should navigate to diffrent page in same taskflow. How to do that.Little tricky
According to calendar component we can have this navigation easily by the child component or from the calendar facet. We can have a show a popup
in the activityHover facet. In the popup window we can have the button ,inside the button action property we can define the control flow case or some string which we defined in the taskflow diagram for navigation. If you do like this when you hover over the calendar activity a pop up window will come and you will get button with some other detail , when you click the button you will be navigated to new page. look easy…….

But my requirment is navigate after clicking the acitivity . Then i made that button visible property to false .I created a managed bean and inside the activityListener of calendar component i wrote a method and invoke the button action programmatic and queue the action event as i described in my old post

 
        UIComponent component = null;
        FacesContext facesContext = FacesContext.getCurrentInstance();
        if (facesContext != null) {
          UIComponent root = facesContext.getViewRoot();
          component = findComponent(root, "buttonId");
        }
        
        
        // UIViewRoot root = facesContext.getViewRoot();
        //cb1 is the fully qualified name of the button
        RichCommandButton button = (RichCommandButton)component;
        ActionEvent actionEvent = new ActionEvent(button);
        actionEvent.queue();