Microservices, Tomcat, memory leak, migrating SpringBoot to 1.3.x

Situation:
I had to investigate an issue with one of our CI servers, which also is used for testing (don’t ask why).

This particular server is used to deploy multiple SpringBoot micro services, in a single tomcat. (again.. don’t bother).

This blog is just a log of investigation and resolution around that issue.

Our rest based SpringBoot micro services deployed within single tomcat were not responding to requests and thus timing out.

Task
Well my task was to bring them back up so testing could proceed.

Action
Like wise men say, always look at the logs, so after doing some quick system wide memory and disk checks, i decided to adhere to the wise men.

Wala! within logs i found this love note:

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread
Exception in thread java.lang.OutOfMemoryError: PermGen space

Every java programmer eventually realizes, PermGen actually means the java process has consumed all of it’s allocated memory and can’t do much anymore.

One quick and dirty solution is to restart the process, in this case Tomcat. Which i did, but after taking a backup of log file, just in case if i bump into a wise man.

Something must be causing this memory leak, and if unattended we would end up in same situation again. Thus root cause analysis was required. Further log analysis highlighted this warning message:

SEVERE: The web application [/users] created a ThreadLocal with key of type [org.jvnet.hk2.internal.Utilities$2] (value [org.jvnet.hk2.internal.Utilities$2@16d52580]) and a value of type [java.util.WeakHashMap] (value [{}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

This warning clearly suggests when SpringBoot based services are shutting down (by Tomcat Manager due to CI), the threads are not stopped properly thus they remain ‘Running’ and holding up any memory they acquired. After a few deployments and restarts this would make tomcat unresponsive for new requests.

Quick googling revealed hk2 is a Dependency Injection framework used by Jersey, which is a managed dependency within SpringBoot. Luckily this issue had already been fixed by developer community of hk2 and Jersey ver 2.21 is updated to use it. All I had to do was to update our SpringBoot version from 1.2.7 to 1.3.x.

Below are a few project specific unrelated issues that I faced when upgrading SpringBoot.

Problem:

error: cannot find symbol
symbol: method filter(List,Predicate)
location: class Iterables

Solution:
Turns out we were using guava classes that were originally packaged within Jersey.
Since Jersey project has extracted and packaged them seperately they were not in classpath anymore.
Instead of using jersey’s new package, just decided to include Google Guava directly in gradle like so:

compile ‘com.google.guava:guava:19.0’

Problem:

warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning

Solution:
JAVA_HOME for User was set to 1.8 while JAVA_HOME globally was set as 1.7

Problem:

C:\…..spring-context-4.2.7.RELEASE.jar(org/springframework/context/annotation/PropertySource.class):
warning: Cannot find annotation method ‘value()’ in type ‘Repeatable’: class file for java.lang.annotation.Repeatable not found
1 warning

Solution: (Didn’t Work for me)
Use @PropertySources to wrap @PropertySource and suggested here, here and here

This solution didn’t work for me, So went ahead and removed this annotation, all tests still passed, so this was an acceptable solution for now.

Result
Our CI server is running smoothly for few days now. Happy Days!

Watcher – Google Chrome Extension

Watcher liberates developers from hitting Refresh (F5) again and again during development. Upon detecting a change in user selected source files, included on current page, this DevTools extension will automatically refresh inspected page to reload watched resources.

In modern rapid web application development environments e.g. Node.js, this extension compliments utilities like nodemon and supervisor to fully automate the development process, as developers can see their changes in real-time.

You can find ‘Watcher‘ extension in Google Chrome Web Store.

Feel free to drop your questions & feedback here.

Agile Meetings – Daily Status Meeting (Stand-up Meeting)

**adsense_4x1Block**
Agile Development Model inherits all of its practices from its composing methodologies, for example Scrum. One such practice in life cycle of a Scrum is to conduct Daily Sprint Status Meetings.
Daily Sprint Status Meetings (or Stand-up Meetings) are very crucial for implementing agile process in its true spirit and eventually for the success of that project.
Failure to adhere to these best practices will not result in very visible and immediate consequences; rather it will cost slow and gradual departure of overall team spirit and efficiency. Due to this subtle footprint of results of not pursuing these best practices, Scrum Master needs to be extra vigilant of these guidelines and must course correct at the first sight of non-compliance.
Below are some characteristics and best practices for conducting a Daily Sprint Status Meeting.
Agenda: To give daily status on:
a) What was completed today
b) What will be worked on tomorrow
c) If there were any blockers

Participants: Whole Team and Scrum Master
Recurrence: Every Day
Time Limit: 15 mins

Sprint Status Meeting Best Practices:

  • Daily Sprint Status Meeting must not exceed more than 15 minutes.
  • Keep daily status meeting focused on its purpose and agenda, do not mix agendas of other agile meetings with daily status meeting.
  • Minimize the distractions e.g. turn your electronics off.
  • Daily Sprint Status is also termed as Daily Stand-up meeting because it is recommended to conduct this meeting while all participants are standing in order to remain concise, attentive and then get on with their work briskly.
  • Attach fines to late comers in order to associate a sense of discipline to the Daily Stand-up meeting.
  • There should be a clear sign that the stand-up is over to avoid the feeling of being left out in participants.

Secure Shell (SSH) keys generation using Putty on Windows

**adsense_4x1Block**
Secure Shell or SSH is a network protocol that allows data to be exchanged using a secure channel between two networked devices.


With more computing and data storage moving to cloud, secure communication between machines is inevitable. For enabling that secure connection SSH is widely used.


SSH uses Private-Public Keys to establish the authenticity of sender and receiver. More on that here on wiki.


For generating this key pair, if you are using Windows here is what you should do:


1. Make sure you have puttygen. You can download it from here:

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

After you have downloaded the program please run the program

2. Make sure SSH2 RSA is selected.

3. Press Generate, and provide entropy for the key by moving the mouse around.

4. Change the Key comment field to some meaningful description.

5. Enter a passphrase which is used to encrypt the private key.

6. Save the public key.

7. Save the private key.

8. To save the public key in the OpenSSH2 format (required for EC2):

Select all of the text as shown, and copy to the clipboard

Then paste the OpenSSH2 version to a new text file, for example yourname_rsa_new.pub.



Once you have the public keys generated you can use public key for communicating with other machines over network for example Amazon EC2 instances.

Feel free to share your experience regarding generating keys on different machines.

Struts Framework – Using Custom Class as Struts Action Controller

**adsense_4x1Block**
Introduction:



In this struts framework tutorial we will customize default Struts Action’s configuration so that it will use our custom java class to process the request and then navigate user back to appropriate page.


Along the way, we will also set folder structure of basic Struts Project so that it can be extended for larger complex projects with ease in future. Also a basic example of Model-View-Controller (MVC) design pattern will be implemented so that you can identify different components of a Struts Project going on forward.


Near the end we will have a taste of Struts Tags library to easily access variables defined within Action handler.


In case at any point during this tutorial you are confused about how things are working, you are highly recommended to read this Hello World! – Struts Framework Tutorial first, to develop an understanding of basic flow of Struts Application.



Tutorial’s Technology Stack:

Struts – 2.2.3
Eclipse – Helios



Download Starting Code:

Tutorial Starting Code: Download

How to Use: create a blank Dynamic Web Project using Eclipse naming “Tut-StrutsWithCustomAction”, and copy contents of this download to it. Refresh project in Eclipse and deploy on tomcat server to run this web application.



Step 1: Understanding Course of Action

The starting code for this tutorial has a simple navigation case implemented having two JSPs and two default Actions defined in strtus.xml against them.

We learned in Hello World tutorial that if ‘class’ attribute is not defined for Action tag in struts.xml, then by default com.opensymphony.xwork2.ActionSupport class is invoked in background which simply returns a success message. This success message is used by ‘result’ tag (default behavior again) to load page defined in it.

1
2
3
<action name="hello">
	<result>/jsp/hello.jsp</result>
</action>

What we will achieve in this tutorial is to override the default behavior of ‘action’ tag in order to use our Custom class. This way we can work with our Model objects, perform action, store information and return a custom View, thus practicing the complete MVC flow.



Step 2: Setting folder structure for Struts Project

We will organize our custom classes so that Struts Project’s folder structure remains maintainable as the project grows. Idea is to separate all Action controllers in action package, and model classes in model package. So let’s create Model and Action classes in next steps, their package names will setup the required folder structure.



Step 3: Creating Model Class

We will create a basic class to mimic a Model object, so that we can see how Model objects are going to be used in custom Action controllers of a Struts based web application.

Create a class (Right click on Project > New > Class) with following lines of code with package ‘sawan.hello.model’ and name ‘MessageStore’, leaving everything else as default. (The class implementation is borrowed from Apache Struts Tutorial written originally by Bruce Phillips).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package sawan.hello.model;
 
/**
 * Model class that stores a message.
 * @author Bruce Phillips
 *
 */
 
 public class MessageStore {
 
	private String message;
 
	public MessageStore() {
 
		setMessage("Hello Struts User");
	}
 
	public String getMessage() {
		return message;
	}
 
	public void setMessage(String message) {
		this.message = message;
	}
}



Step 4: Creating Class for custom Controller

Now will create a simple Java Class which in next step will be promoted to a Struts Action controller, so that we can understand how Struts framework is adding capabilities to plain old java objects (POJOs).

Create a class (Right click on Project > New > Class) with package ‘sawan.hello.action’ and name ‘HelloWorldAction’.

Following lines of code are generated automatically in the blank class by IDE.

1
2
3
4
5
package sawan.hello.action;
 
public class HelloWorldAction {
 
}

This class is going to use an object from our Model i.e. MessageStore class. So let’s create an instance variable within HelloWorldAction.

Add this line of code between curly brackets.

1
private MessageStore messagestore;

IDE will complain for ‘MessageStore’ cannot be resolved to a type, and it will highlight MessageStore type in our variable declaration.

Tip: In Eclipse, Simply click and hover over MessageStore class name and in proposed list of quick fixed select Import sawan.hello.model.MessageStore.

Hint: IDE was able to locate this class because we have Struts jar dependencies in WebContent/WEB-INF/lib folder.

Adding import statement before class definition will resolve this issue.

1
import sawan.hello.model.MessageStore;

Next we need to create getters and setters for this class variable.

Tip: In Eclipse, select Source > Generate Getters and Setters to auto generate them.

Following methods should be added under our variable declaration.

1
2
3
4
5
6
7
	public MessageStore getMessagestore() {
		return messagestore;
	}
 
	public void setMessagestore(MessageStore messagestore) {
		this.messagestore = messagestore;
	}

So far our HelloWorldAction class is a POJO having no Struts capabilities. We’ll add them next.



Step 5: Converting a POJO Class into a custom Struts Action Controller

This transformation needs two changes to our class and we’ll be all set.

Change 1: First of all, our class should inherit from ActionSupport class defined in Struts framework. Extending this class will not only force us to implement some predefined interfaces, but our class will also inherit some methods and properties from ActionSupport class and its parent classes. This is what inheritance does.

So let’s add ‘extends ActionSupport’ next to our class declaration, so it will look like:

1
public class HelloWorldAction extends ActionSupport

Tip: Once again, IDE will complain for unavailable ActionSupport class, so clicking and hovering will propose a quick fix to import import com.opensymphony.xwork2.

Adding this import statement will resolve this issue (if not automatically added for you):

1
import com.opensymphony.xwork2.ActionSupport;

Change 2: Second change to our HelloWorldAction is to provide an entry point for Struts front controller (defined in web.xml). Struts implements this interface by providing a class method named ‘execute’.

Also execute method must return a string.

So let’s add execute method.

1
2
3
4
public String execute()throws Exception
{	
    return SUCCESS;		
}

The variable SUCCESS is inherited from ActionSupport class, which inherited it from Action class, both being part of Struts Framework and are included in package com.opensymphony.xwork2.

Once our execute method is available, we need to initialize our ‘messagestore’ class variable so that it will be made available to resulting view.

Add this line of code within execute method to initialize class variable with our Model object.

1
messagestore = new MessageStore();

After both Step 4 and 5, our HelloWorldAction.java class should look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package sawan.hello.action;
 
import com.opensymphony.xwork2.ActionSupport;
 
import sawan.hello.model.MessageStore;
 
public class HelloWorldAction extends ActionSupport {
 
	private MessageStore messagestore;
 
	public String execute()throws Exception
	{
		messagestore = new MessageStore();
		return SUCCESS;		
	}
 
	public MessageStore getMessagestore() {
		return messagestore;
	}
 
	public void setMessagestore(MessageStore messagestore) {
		this.messagestore = messagestore;
	}
}



Step 6: Adding custom Action configuration to struts.xml

Our custom Action class is ready to handle requests. But we have not told our web application, which requests should be forwarded to this Action controller.

Open src/struts.xml file. There are couple of actions already defined in downloaded source code. Let’s add our custom action after those.

Add following configuration block between ‘package’ opening and closing tags.

1
2
3
<action name="helloaction" class="sawan.hello.action.HelloWorldAction" method="execute">
	<result name="success">/jsp/helloaction.jsp</result>
</action>

What this Action configuration does is:

1. it defines a name for this action as ‘helloaction’, which will make it searchable by Struts front controller (one defined in web.xml).

2. class attribute sets the class which should be passed the execution.

3. method attribute defines the method name, which should be passed the execution in that class.

4. result tag, declares that when execution method finishes with a returned message, application should return /jsp/helloaction.jsp View.

5. name attribute within result tag, tells that redirect user to said page, only if message returned from execute method is success.

With this configuration we have set enough directions for our front controller defined in web.xml i.e. org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

However there is no ‘helloaction.jsp’ page defined yet, to which we are redirecting the user after successful exection, so we need to do that next.



Step 7: Adding result View for our custom Action

Create a new jsp page in ‘WebContent/jsp/’ folder named ‘helloaction.jsp’.

At this point since all required files and folders are created, so our project hierarchy should look like this when seen in Project Explorer.

Struts With Custom Action - folders and files in Project Explorer view

Folder structure when all required files are created

If we launch our application at this point, it will be launched fine, however there is no way to trigger a request to ‘helloaction’, which when intercepted by front filter, is redirected to our custom Action class.

Thus, we need to make changes to our index.jsp page, so that there is a link which we can hit to trigger all that. Change existing line of html code between body tags of index.jsp, to something like:

1
Index Page | <a href="hello">Struts</a> | <a href="helloaction">Custom Action</a>

Now if we launch our application index.jsp page will be displayed as default entry point.

Struts With Custom Action - default view for our application

Index page for our application

Clicking on ‘Custom Action’ link will generate this url request:

http://localhost:8080/Tut-StrutsWithCustomAction/helloaction

This request will be intercepted by our front filter, and it will look in struts.xml for a matching action name. Since it has truncated everything else, and only looking for ‘helloaction’, it will find it for sure, since we just added it during struts.xml configuration step above.

Front controller will pick the class name from ‘class’ attribute and pass the execution to ‘execute’ method of this class, just as defined in Action configuration. So execution will enter in execute method of our custom Action class’s execute method.

Once there, we have initialized the messagestore class variable with MessageStore, our model class, and simply retuned SUCCESS.

When execution comes back to front controller, it will use ‘result’ tag to determine which page to launch based on the value of returned string. Since we have returned SUCCESS and there is a result tag, with name success, front controller will redirect browser to helloaction.jsp

Hint: It is a common and recommended approach to define class variables within Action class with required values returned by Model. So that resulting view will only have access to values which it needs to display.



Step 8: Using Struts Tag Library to access variables within Action controller

At this point our basic flow is working fine and we have utilized a custom Action controller for processing our page requests.

However the redirected helloaction.jsp page is blank. In real world applications, we will be doing some processing within execute method, and displaying the results on redirected page (helloaction.jsp in our case).

Struts facilities this functionality very elegantly by providing Struts Tag Library. Using struts tags, we can very easily access properties we have set within Action controller for each request.

For making our helloaction.jsp capable of accessing property defined within HelloWorldAction class, we need to make two changes in helloaction.jsp

Change 1: First of all we need to add Tag Library Directive, so that web server knows how to render Struts 2 Tags when generating a response.

Add this line of code on top of helloaction.jsp page right under page directive.

1
<%@ taglib prefix="s" uri="/struts-tags" %>

Change 2: Secondly we need to use one of Struts 2 Tag to access the property within response, which is available to us within our page scope.

Add this line of code between body tag of helloaction.jsp:

1
<h2><s:property value="messagestore.message" /></h2>

After these changes, our helloaction.jsp should look something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Hello Struts Tag Library</title>
</head>
<body>
<h2><s:property value="messagestore.message" /></h2>
</body>
</html>

Let’s run our web application once again, this time when helloaction.jsp page is rendered, we will see same message defined in our Model object i.e. MessageStore.java.

Using Struts Tag Library to display property defined in our custom Action

Using Struts Tag Library to display property defined in our custom Action



Download Tutorial Code:

Tutorial Working Code: Download



Exercise:

  • Add another custom Action handler along with its configuration in struts.xml file.

  • Use any other message besides “Success” returned from execute method. Use messages defined in Action interface within Struts 2 API.


    Hint: You will also have to make changes in struts.xml so that result will respond to that returned message.

  • Can we use different method name besides execute in struts.xml ? will that method act as our default entry point if we satisfy the requirement of returning a string from that method?


Hello World! – Struts Framework Tutorial

**adsense_4x1Block**
Introduction:


In this tutorial we will develop our Hello World java Web Application using Struts technology. The Apache Struts web framework is a free open-source solution for creating Java web applications using Model View Controller (MVC) design pattern.

Let’s get started with a very basic tutorial that will expose limited capabilities of Struts framework, but it will serve as a good starting point to explore Struts further by understanding the initial configurations required.

Tutorial’s Technology Stack:

Struts 2.2.3
Eclipse Helios (But you can do same steps with NetBeans as well)



Step 1: Creating Java Web Project in Eclipse IDE

This tutorial assumes you already know how to create new Java based Dynamic Web Project in Eclipse. If not, then you must first acquire some understanding using this basic JSP Tutorial

To continue we need a new Web Project, named ‘Tut-StrutsHelloWorld’ with index.jsp page added.



Step 2: Customizing JSP Page and Adding Navigation

Before diving into Struts let’s create a simple case of navigation to verify Struts working. Besides an index.jsp page in WebContent folder, add another jsp and name it ‘hello.jsp’

Refer this page from index.jsp, by pasting this line of code between body tags.

1
Index Page | <a href="hello">Struts</a>

Let’s add some custom text in ‘hello.jsp’ as well so that page is not rendered blank. Add following line of code in ‘hello.jsp’ between body tags:

1
<b>Hello World! Struts Application</b>

With this we are all set as far as our basic navigation is concerned.



Step 3: Adding Struts Capability to our project

Struts capability can be added in a project by simply adding its distributed jar files. Download latest Struts distribution from Apache Struts project site. This tutorial was written using Struts 2.2.3, so same or later can be downloaded.

Extract files from this distribution; some contained folders are described below:

apps: contain sample applications against tutorials on struts project website
docs: this folder contains, documentation for struts plugins, test pages, and whole Apache Struts project website, including tutorials, so that you can work on them offline as well.
lib: this folder contains struts jar files (containing struts implementation) and many other related jars, that you might need to use based on your project’s future needs. e.g. in case you plan to integrate it with Spring, then you’ll need related jar files.
src: since struts itself is an open source project maintained by Apache, that’s why its source code is included in the distribution itself.

Let’s now shop for our desired jar files from lib folder. Copy following jars from distribution lib folder, and paste them in:

Tut-StrutsHelloWorld\WebContent\WEB-INF\lib

  • struts2-core-2.2.3.jar
  • xwork-core-2.2.3.jar
  • commons-fileupload-1.2.2.jar
  • commons-io-2.0.1.jar
  • commons-lang-2.5.jar
  • freemarker-2.3.16.jar
  • javassist-3.11.0.GA.jar
  • ognl-3.0.1.jar

These are the minimal jars that you’ll need for Struts 2.2.3. Of course the version number may vary based on which distribution you have downloaded.

Are you wondering, there are so many jars in lib folder within Struts distribution, how on earth would I know which jars to pick up and which to leave? What I did was, at first added struts2-core-2.2.3.jar only, and Ran the application within Eclipse. There was an exception stating ‘class not found’ giving package name in which it looked for the class.

That package name helped me identify the jars required from lib folder, so I picked it and copied that jar to my project’s lib folder (Tut-StrutsHelloWorld/WebContent/WEB-INF/lib). I repeated this step unless there was no exception in Console. So it is up to you now, if you want you can go through this exploration step or you can simply pick the ones I have already listed.



Step 4: Telling Server we are using Struts

At this point if you will run your project on Server, nothing will happen. Since we just added some jars and they are sitting there doing nothing, unless we use some object from Struts implementation in these jars.

For enabling Struts 2 framework to work with our web application, we need to add a special Servlet, implemented by Struts called ‘StrutsPrepareAndExecuteFilter’, which is responsible for initializing Struts 2 for our project.

Since it is a Servlet, and from Hello World – Servlets Tutorial, we know that Servlets need to be loaded by Web Server (e.g. Tomcat) when application is deployed. And Web Server reads this information from entry point of our web project i.e. web.xml, the web application descriptor file.

So Add this code in web.xml between web-app tag.

1
2
3
4
5
6
7
8
9
<filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
 
<filter-mapping>
  <filter-name>struts2</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

The Servlet that initializes Struts 2 is a special Servlet with filtering capabilities thus called Filter. A Filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both. Filters are actually an interface based on Servlets, thus they are basically Servlets.

Thus we added two nodes ‘filter’ and ‘filter-mapping’, rather than usual ‘servlet’ and ‘servlet-mapping’, since filter is a Servlet in effect, but just a little special.

Also note that, url-pattern node value is /* meaning the Struts 2 filter will be applied to all URLs for this web application. Thus it acts as a front filter and controls what should be done with each request to our web project’s internal resources. Hence acting as a Controller, making C part of MVC.



Step 5: Configuring our Struts 2 Implementation

The Filter Servlet we created above, needs a configuration file to know, what it should filter and how to behave with incoming requests (i.e. when new page is requested by the user). This configuration is actually what customizes Struts 2 for our web application.

So create a new file named ‘struts.xml’ , and place it in Tut-StrutsHelloWorld/src folder (struts.xml must be on the web application’s root class path)

Add these lines of code in src\struts.xml file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>
      <!— Makes struts to output more error information in console in devMode  -->
	<constant name="struts.devMode" value="true" />
 
	<!— has nothing to do with java packages, simply used to group actions (below).
    	    name attribute can have any value. Extend it from struts-default -->
	<package name="hello" extends="struts-default">
 
		<!—  action for index.jsp page -->
		<action name="index">
			<result>/index.jsp</result>
		</action>
 
		<!-- action for hello.jsp -->
		<action name="hello">
			<result>/hello.jsp</result>
		</action>		
	</package>
</struts>

Note: Struts 2 can use either an XML configuration file or annotations (or both) to specify the relationship between a URL, a Java class, and a view page (such as index.jsp). For our basic Struts 2 application, we’ll use a minimal xml configuration.



Step 6: Understanding Basic Flow of Struts Application

Very important to understand what these lines of configurations will tell our StrutsPrepareAndExecuteFilter and what is happening in the background.

Within the Package named “hello” we have grouped two Actions. Actions are Fundamental component of Struts framework. From Apache’s website:

“An Action is an adapter between the contents of an incoming HTTP request and the corresponding business logic that should be executed to process this request”

meaning, when our application launches, web server reads the web.xml. it finds welcome-file-list tag, and in that it tries all welcome-files including index.jsp, to launch default request to our application’s index page.

Remember? the Servlet filter we have configured in web.xml has a filter-mapping defined so that it will listen to every request (/* )coming to our application. So it will kick in, as soon as web server launches a request to find our index page. Now what Struts filter will do is, first of all it will remove all the unnecessary strings from the Request URL. e.g. in case of this URL:

http://localhost:8080/Tut-StrutsHelloWorld/index.jsp

Filter will remove the host and project name, and also the .jsp extension. Taking only ‘index’. That’s how Struts is implemented.

Now it will take that request (whatever is left of it) and scan through struts.xml, in top down sequence, and try to find an Action that has exact same name as this sub-string.

Yes it will find it since we have defined an Action with name attribute set as ‘index’. So now what.

Once matching Action configuration is found by the Filter, it will call the java Class associated with that Action. What? Which class, there is no class association in configuration. Yes, for hello world struts tutorial, I have kept it simply, and to the defaults. So when the class attribute in an action mapping is not defined, the com.opensymphony.xwork2.ActionSupport class is used as a default.

Had there been a class defined, filter would pass the execution to ‘execute’ method defined by our custom class. By default since ActionSupport class is used, so it’s execute method returns a string “success” by default.

what will we do with this string “success”? actually < result > tag within Action will do. By default result tag listens and responds to “success” message. So when it received the success message from ActionSupport by default, it redirected our browser to page named /index.jsp.

Now when index.jsp page is rendered, it has a link to “hello”. Clicking on will generate a request to webserver, which it will redirect to filter listening to all requests within our application. Filter will go through the above process once again, this time matching the Action named “hello” instead and showing the result “hello.jsp” page this time.



Step 7: Running our first Struts based Web Application

So now with this understanding, we are good to build and deploy our first Struts based web application on web server. Provided web server is configured with Eclipse IDE, right click on project name and select Run As > Run on Server. Built in browser will be launched with first showing the index.jsp page, and clicking on Struts link will navigate to “hello.jsp” after going through the background Struts Actions mapping mechanism.



Hello World Struts - rendered index page

Hello World Struts - rendered index page



Clicking on Struts link will navigate to hello.jsp.



Hello World Struts - rendered hello strutspage

Hello World Struts - rendered hello strutspage



Exercise

  • Rename the Action’s name attribute for hello, to something else. Where else do you need to change the action name?

    Hint: compare the code snippets above and see where that name matches.

  • Add a link on index page for a third page and call it mystruts.jsp. Add required configurations in struts.xml to make this new navigation work. (Hint: you need to add an Action)
  • Go through the Configuration Elements Documentation and read about different elements.

Hello World! – Servlets Tutorial using Eclipse IDE

**adsense_4x1Block**
Introduction


There are many Hello World! Servlet tutorials out there, but when I wanted to learn Servlets, none of these tutorials gave complete information, at least what should be given at that point to not just only create a Hello World Servlet, but to enable new comer to start thinking on the lines of how he can utilize power of Servlets in his own web project.


In this tutorial we will create our very first Servlet, and along the way develop some understanding about what Servlets are and how they play their role in a Java based Dynamic Web Project. If you are looking for a shorter hello world tutorial, then stop and search again.


Still there? Ok, Let’s have a quick 10,000 foot overview of Servlets in plain English, and develop some understanding for the scope of this tutorial:


  • Servlets are created for Java Web Projects. That is why Servlet Specification is part of JEE Platform (for Web Projects) rather than JSE Platform (for Desktop Projects).

  • A simple Java class when inherited from GenericServlet or any of its subclasses (normally HTTPServlet), inherits all the power that is built into Servlet API (Power of communicating with Web Server and doing stuff there).

  • You can think of Servlets as Plugins for the Web Server, on which your Web Project is going to be deployed. So with these plugins your application can perform custom actions (since you wrote these Servlets yourself) on the web server

  • When your web application is deployed, Web Server registers and loads all of your Servlet classes. So now web server knows what custom action to perform, when your application calls any of these Servlets.

With theses high level concepts, we are good to create our very first Servlet.



Step 1: Creating New Java Project

For this tutorial we will need a new Java Dynamic Web Project with an index.jsp page included as first landing page. If you are not comfortable with how to do that, I would recommend you to stop right here and complete this Hello World – JSP tutorial first.



Step 2: Adding a Servlet to your Web Project

Right click on project name in package explorer in Eclipse IDE, and select New > Servlet. ‘Create Servlet’ wizard will pop-up.

Wizard Screen 1:

Some project information is already filled. Let’s fill the blank fields.

Java Package: you can name your package anything. This name will be used for creating folder hierarchy under src folder in your project. Let’s say ‘servlets.hello’
Class name: Again your Servlet, your choice. I would suggest ‘HelloWorld’
Superclass: is by default set as ‘javax.servlet.http.HttpServlet’ since most of the time Servlets are used as HTTP request handlers on Web Servers (don’t worry I’ll explain it in a bit). However Servlets can be used on other Server types e.g. Mail or FTP Servers. Leave this field as is.

Eclipse Create New Servlet - Wizard Screen 1

Create New Servlet - Wizard Screen 1

You could press Finish, but let’s see what other options are available to customize our Servlet. Press Next button.

Wizard Screen 2:

Description: Enter anything useful that will describe your Servlet.
URL Mappings: Hm sounds interesting. I don’t know what it is. Let’s edit it to something else. Say “/HelloWorldMapping” (clicking on it will activate the Edit button). . don’t forget to put /

Eclipse Create New Servlet - Wizard Screen 2

Create New Servlet - Wizard Screen 2

Wizard Screen 3:

On third screen, all methods available to be implemented by our Servlet are listed. Since we are going to do a basic example, so let’s keep them to defaults i.e. doGet and doPost methods.

Eclipse Create New Servlet - Wizard Screen 3

Create New Servlet - Wizard Screen 3

Pressing Finish will do some stuff in background and IDE will open the newly created Servlet class.



Step 3: Making JEE Available – OPTIONAL

If you continued from “Hello World! – JSP” tutorial, or otherwise your Eclipse IDE has Tomcat Server configured, then you won’t see any error messages stating:

“The import javax.servlet cannot be resolved”

Since, Tomcat Server you have configured, already has ‘servlet-api.jar’ in its /lib folder therefore Eclipse won’t complain and it will find required jar in Project Build Path (Right Click on Project > Properties > Java Build Path > Libraries > Expand Tomcat’s Library).

When there are no errors reported by Eclipse, simply Skip this step and jump to Step 5.

Otherwise you will have to manually download and add Servlet support for your project. Reason being Servlets are part of Java Enterprise Edition (JEE) SDK Specification, thus we need to provide JEE binary (jar) to our web project. Here is how to do it.

Download JEE API binary distribution from any of these Maven repositories.

For Java EE 6: http://download.java.net/maven/2/javax/javaee-api/6.0/javaee-api-6.0.jar
For Java EE 5: http://download.java.net/maven/1/javaee/jars/javaee-api-5.jar

copying one of these javaee-api-x.x.jar to your java web project’s lib folder (Project/WebContent/WEB-INF/lib) and building your project (Eclipse > Project > Build Project ) will resolve these errors and add JEE Servlet capabilities to your project.

For those who are still wondering why this step was at all required here’s a pointer. In your generated Servlet class, it has:
‘extends HttpServlet’

The HttpServlet class, and much more are already compiled and packaged in javaee-api-x.x.jar we just added, so we and eclipse needed it to run our project.



Step 4: What has happened under the hood

Let’s see by adding blank Servlet, what changes are made to the project automatically by Eclipse. Knowing this is very important because advanced java technology tutorials will assume that you have done these steps when they ask you to add a Servlet.

servlets.hello.HelloWorld
Once wizard has finished, it opened the HelloWorld Servlet class. This class is created in src/servlets

hello/HelloWorld.java

This folder structure is created based on package name we provided on Wizard Screen 2

web.xml
Open WebContent/WEB-INF/web.xml file. With this new Servlet, two tags are added into web.xml file. and

1
2
3
4
5
6
7
8
9
10
11
  <servlet>
    <description>Servlet to print out Hello World!</description>
    <display-name>HelloWorld</display-name>
    <servlet-name>HelloWorld</servlet-name>
    <servlet-class>servlets.hello.HelloWorld</servlet-class>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>HelloWorld</servlet-name>
    <url-pattern>/HelloWorldMapping</url-pattern>
  </servlet-mapping>

As we know, this web.xml file is used by the Web Server (e.g. tomcat) to become aware of all the components of our Web Application. So upon startup, Tomcat will read this web.xml file and create a Servlet with this servlet-name as an instance of servlet-class.

Once Servlet is created, Tomcat will wait for any HTTP requests, which are addressed to this Servlet.

Here comes the second tag ‘servlet-mapping’, this actually helps tomcat to identify which HTTP requests are addressed to which Servlet. The url-pattern attribute is what we customized, so any request that has /HelloWorldMapping at the end, will be passed to this Servlet’s doGet or doPost methods.

HelloWorld.java
Let’s now look at default Servlet class generated for us by Eclipse. Here is how it looks like in effect (without comments)

package servlets.hello;

defines where this class is located in src folder.

1
2
3
4
5
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

These imports make required Servlet classes available for compiling. They are packaged inside servlets-api.jar (or javaee-api-x.x.jar if you downloaded that one), which provides contract implementation between your Web Server and Servlet class. Based on this contract between these two entites, Web Server can send information to Servlet and Servlet can communicate back in server understandable format.

1
public class HelloWorld extends HttpServlet

In Above line, ‘extends HttpServlet’ is what gives all the built in power of Servlets to your otherwise simple Java Class.

1
2
3
4
5
6
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
}

Above doGet and doPost methods will receive information from the Web Server, based on whether Request was a Get or a POST. Whenever server will realize some HTTP Request is addressed to this Servlet, server will create a HTTPServletRequest object, and pass it to one of these methods.

Web Server will also pass a HTTPServletResponse object to the Servlet, so that Servlet can do its custom processing, update or insert information in response object, and finish its processing. Server takes the control back, and based on updated response object, it will display the output in browser.

That is the contract implemented by javax.servlet packages.



Step 5: Customizing our Servlet with Hello World Message

Ok now we will quickly do some customizations and see how this all works.

Add this line of simple HTML code between body tags in index.jsp

1
<a href="HelloWorldMapping">Invoke Servlet</a>

Note: We will use only the ServletMappingString in link, and no need to append it with / since current jsp’s context URL will be automatically appended and resulting Request URL will be something like:

http://localhost:8080/Tut-ServletHelloWorld/HelloWorldMapping

Above link will simply generate an HTTP Get request. Which you have correctly guessed is URL Mapping for our Servlet. At the first sight of this URL, Tomcat will run to our Servlet, and hand him over the Request and Response objects to play with. HelloWorld Servlet will do some magic, update the response object and finish processing. Tomcat will get notified and it will simply draw that response on screen. (By the way, we can control this flow, but that is out of the scope of this tutorial).

Let’s add that magic logic in our Servlet. Add this snippet of code in doGet method stub. So it should look like:

1
2
3
4
5
6
7
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("Hello World!");
		out.close();
}

In these four lines of code, we are adding our customization to Tomcat’s Response Object for original Get Request. We set the content type of the response, so that browser can render it fine. Then we get the PrintWriter from response object (just implementation details, ignore them for now), and print a line to that stream. Finally we close the stream.



Step 6: Hello World Servlet in Action

We’ll now need to build our project prior to running it on server so that changes made in Servlet class are compiled.

From top Eclipse menu select Project > Build Project (If Build automatically is not selected in same menu. If it is, then no need to build manually and ignore this step.)

Right click on Project and select Run As > Run on Server. This will compile our Servlet class and launch index.jsp. Index page should contain simple html link to ‘HelloWorldMapping’.

Clicking on this html link will generate a request, which will go through the process explained above and return our custom response to browser.

Hello World Servlet Response in browser

Hello World Servlet Response in browser

There it is, a completely web server generated HTML page, using our Servlet of course.



Exercises:

  • Customize the Hello World message string to something else, say include your name in message and Right click on Project > Run As > Run on Server.

  • Include an html anchor tag (just like we added in our index.jsp), but this time point it to index.jsp rather than Servlet Name. See if you can link your Servlet generated html page back with index.jsp page.


    Let’s use these two lines:

    1
    2
    
    	out.println("</br>");
    	out.println("<a href='index.jsp'>Index Page</a>");

Hello World! – JSP Tutorial using Eclipse IDE

**adsense_4x1Block**


This tutorial summarizes steps involved in creating simple Java Dynamic Web Project using Eclipse IDE and adding your very first JSP page in it.

We will also configure Tomcat Web Application Server with Eclipse and deploy our one page jsp web application on tomcat, from within Eclipse.

Step 1: Required Installations

Just to make sure for new Java enthusiasts (target audience for this tutorial), all required components are installed for creating first JSP Web Application.

JRE: Can’t be more simple yet comprehensive than this guide here
Tomcat: Use this guide here for latest Tomcat Installation
Ecplise: Use following tutorial for installing Eclipse. Use section specific to your environment.

Step 2: Configuring Eclipse for JRE and Tomcat Server

Being independent installations, we’ll need to configure our Eclipse IDE so that it will know where is our Java Runtime Environment located and which Web Server to be used for running our jsp web application.

Configuring JRE in Eclispe: In Eclipse IDE, go to Window > Preferences > Java > Installed JREs. In Installed JRE’s section press Add provide JRE home directory and some name for this JRE. (JRE home is usually C:\Program Files\Java\jre6 .. for windows)

Configuring Tomcat in Eclipse: In same Preferences Dialogue open Window > Preferences > Server > Runtime Environments. Press Add button for launching Add Server Wizard. Walk through the wizard selecting appropriate Tomcat Server version you have downloaded above, and setting the correct Tomcat installation directory. Above installed JRE will be set as Workbench default JRE.

Step 3: Creating Blank Java Dynamic Web Project

We’ll create a blank java web project using Eclipse so that we can add our first JSP page in it and deploy it on configured Tomcat Web Server.

In Eclipse select, File > New > Other, type ‘Dynamic’ in Wizards search field. Results will be filtered to list ‘Dynamic Web Project’ wizard. Select this wizard and press Next.

Creating a dynamic web project in eclipse for our hello world jsp tutorial

Dyanamic Web Project Wizard in Eclipse

Pressing next will launch extensive ‘Dynamic Web Project’ wizard. Enter Project Name and location to create this Project. ‘Hello-JPS’ in our case. Complete this wizard with default settings on steps and press Finish.

New Project Properties Wizard

New Project Properties Wizard

With default settings, and ‘Java’ perspective set in Eclipse (Window > Open Perspective > Other > Java), anatomy of newly created blank Web Project will look like this in ‘Package Explorer’ panel:

Anatomy of new project in eclipse

Folder structure for newly created project in package explorer

web.xml
Within WEB-INF folder, a deployment descriptor xml file is created by Eclipse. This descriptor file is used by Tomcat server, when application is deployed on it, to identify different components of this application and how to use them.

By default a tag is already created in web.xml containing multiple entries for suggested landing page name for our application. Although these pages are not created yet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Hello-JSP</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

So if we create a new page with one of these names, and just deploy our web project on tomcat, it will automatically know which page to use as first landing page.

Step 4: Creating Hello World JSP Page

So let’s just create our first JSP page (File > New > Other) this time enter ‘JSP’ and select ‘JSP File’ wizard. On ‘Create a new JSP File Wizard’ enter file name ‘index.jsp’ and select ‘Hello-JSP’ project. On next wizard page ‘Use JSP Template’ and select ‘New JSP File (html) template. Preview of the code for generating JSP page is displayed as well.

Once finished, a new index.jsp page will be created in WebContent folder. If not created in WebContent folder, move it inside.

Open index.jsp page and enter following line of JSP code between HTML body tags.

1
2
3
4
5
6
7
8
<%-- This is a JSP Comment before JSP Scriplet --%>
<%
	//Prints out to console
	System.out.println("Hello World in Console!");
 
	//Prints out to HTML page
	out.println("Hello World!");
%>

This simple code contains a JSP Comment, and a JSP Scriptlet (a piece of java code embedded within html code using JSP technology). This Scriptlet will print Hello World! message in two output streams. One is to Console and other one is to Response output stream when server is executing this java code in Response to a client Request.

Detailed JavaServer Pages Technology specifications can be found on Oracle website that will explain in depth how JSP pages are rendered on Server side and how they generate Dynamic Content inside an otherwise static HTML page.

Step 5: Deploying JSP Web Application on Tomcat using Eclipse

Time to deploy and run our Web Application Project in browser. Right click on ‘Hello-JSP’ project name in ‘Package Explorer’ panel within Eclipse.

From Project context menu select Run As > Run on Server. This will launch ‘Run on Server’ wizard. Our configured Tomcat server appears in the list, select it and press Finish.

Tip: You can check ‘Always use this server when running this project’ to bypass this step in subsequent project runs.

Clicking on Finish will start tomcat server, and runs our application on it. Eclipse will automatically launch this application in internal browser at URL:

http://localhost:8080/Hello-JSP/

Hint: Or you can copy paste this link any of your installed browsers and they will display the Hello World message. (In this case you won’t be able to see the Console output)

Hitting this URL displayed two Hello World messages, one in Console and other one inside rendered JSP page, just as expected.

JSP print output within web page and on Console

Hello World JSP print output

Exercises:

  • Right click in browser window, within Eclipse, and select View Source. What difference did you see between code we entered in jsp page, and resulting Source view.

  • Change print string to something else, e.g. include your name, save the page and simply refresh Eclipse browser tab. What’s the effect?

  • Add another jsp page in your web project and link two pages with each other using standard HTML Anchor tag. Both pages should have different print strings. (Hint: Create this page in a new folder named jsp under WebContent folder, and link it using /jsp/yournewpage.jsp)

Hello World! – Log4j Tutorial

**adsense_4x1Block**
Objective of this tutorial is to enable you to understand and add basic logging capabilities in your java projects. Starting with a business case of why logging is required, we will cover high level architecture of Log4j and its different components, and finally implement a Hello World example to demonstrate interaction of these components.

In Exercise examples, we will extend our finished code and log4j configurations to use pattern layout and a file appender. Don’t worry about these right now; you’ll learn them along the way.

Introduction:

You must have some programming experience if you are reading this tutorial. So recalling that experience, you will remember one common pattern in your development process, which is inserting debug statements in your code in order to remain informed of where current execution is.

For example in C++ you might have used printf or cout, similarly alert in JavaScript, echo in PHP, trace in ActionScript and similar output statements in other languages.

So what do you use for printing out debug information in Java? … System.out.println(“my message”);

What, then what is Log4j? … You can say Log4j is improved version of System.out.println and one of the major reasons we needed it, is:

When we are developing software, we insert output statements in the code everywhere. Almost Every function has one or more output statements so that we remain notified of which section of code is executed and what is current state of the execution. However when we need to ship this piece of software to client, we have to manually remove or comment out these statements so that they don’t cause unnecessary load on server resulting in slow application response.

Silencing these statements in code means, once you have shipped the binary, you cannot track back a failure or investigate what went wrong, since no one is there to inform you of that.

So we needed some mechanism of controlling debug statement in more configurable way, which we could enable or disable externally without changing the binary. Also being able to silence certain types of debug statements, and letting others print would be a cherry on the cake.

Log4j is exactly that, we insert log4j logging statements wherever in code we would have inserted System.out. And then during development we configure it to print out everything. When shipped to production, we let the logging statements to remain there in code, but configure log4j so that only highly critical information is printed out e.g. exceptions. This way by limiting output, we saved extra processing load on server, while remaining capable of tracking back an issue in software.

Enough on why we needed Log4j, let’s quickly go through different components of Log4j and then implement an example using them.

Overview of Log4j Framework

Log4j is very lightweight and simple logging framework, comprising of three main components.

Loggers: Loggers are basic, developer customized, org.apache.log4j.Logger objects, which provide control mechanism over disabling or enabling certain type of log statements when logged against them.

So we always need a logger in our code to start logging against it. We can either create a new custom Logger (one line of code) or simply use the root level Logger available to us by default.

We can also set the Log Level of these Loggers. The set of possible levels is:

DEBUG < INFO < WARN < ERROR < FATAL

In increasing level of their criticality. So when logging a statement, we tell Logger what is the criticality of each statement, and it will decide later based on external configuration file what to do with this statement.

Appenders: Log4j allows logging requests to print to multiple destinations e.g. console, to a file and much more, these output destinations are called appenders.

So we attach one or more Appenders with each Logger, so that it will send logging statements to all its Appenders.

Default root level Logger has default Console Appender associated with it, thus it prints on Console by default.

Also for example, we can create a custom Logger, and attach it to default logger, to print each logging statement to both Console and an external text file.

Layouts: In order to customize not only the output destination (Appender) but also the output format, a Layout is associated with an Appender.

Layouts may add some additional information to the original text e.g. thread making the log request, level of the log statement or number of milliseconds elapsed since the start of the program.

Workflow of a Logging Statement:

Let’s dry run overall flow of events in a common logging scenario. We initiate a Logger, and send a simple text based logging statement to it, while setting its Log Level. Logger will consult the configuration file, and firstly see if it has to print this Log Level or ignore it, this is done by comparing log level associated with Logger in configurations and log level of the logging statement in code.

If Log Level of logging statement is of equal or greater criticality, then Logger will move on and see which Appenders are associated with it. It will then direct this logging statement to each Appender.

When those Appenders will receive logging statement, they will consult the configuration file, to see what Layout is associated with them. Based on associated Layout formatting is done to original logging text, and finally formatted logging statement is printed out in respective Appender.

While keeping this information in mind, let’s implement a basic Hello World example so that we can see these components in action in code.

Tutorial’s Technology Stack:

Log4j – 1.2.16 (Tutorial should work fine with newer versions as well)
Eclipse – Helios

Initial Code Setup:

How to Use: create a blank Java Project using Eclipse (File > New > Java Project> and name it “Tut-Log4JHelloWorld”.

Step 1: Downloading and Adding Log4j jar in project

Log4j too is distributed as a bundled jar. So in order to add logging capabilities to our project using log4j, our project must know where to find those classes. Let’s download and add log4j’s latest jar to our project. Download latest log4j distribution and unpack it in a folder. Create a folder named ‘lib’ in our java project, and place log4j-1.2.16.jar from unzipped distribution in lib folder.

Now we need to tell Eclipse, where to find that distribution. Right click on project name in Eclipse and select Properties. In Properties wizard, select Java Build Path > Libraries Tab > Add Jars, navigate to Tut-Log4jHelloWorld project’s lib folder, and select newly added log4j.jar file (you might need to refresh the project before doing that).

Fig 1-Creating a Java Class and adding Logging capabilities using log4j

Fig 1-Creating a java class and adding logging capabilities


Step 2: Creating a Java Class and adding Logging capabilities

Let us now create a new Java Class and then add logging capabilities using Log4j into it. Add an empty java class named Log4jHelloWorld (Right click on Project > New > Class, name class Log4jHelloWorld), also select main method to be included.

Newly added class should look like this:

1
2
3
4
5
6
7
8
9
10
package sawan;
 
public class Log4jHelloWorld {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	}
}

Now this simple Plain Old Java Object class (POJO) has nothing special in it. We’ll first use root level Logger available to us by default. Then we’ll see how to create a custom logger.
Add following import statement in class definition.

1
import org.apache.log4j.Logger;

then let’s create a class level variable, and initiate it with reference to default root level logger. Add this line of code inside class definition but outside main method.

1
static final Logger logger = Logger.getRootLogger();

So far we have imported log4j Logger class, and created an object of it as our custom class variable. Next we’ll initiate logging statements against this Logger. Since it is a root level logger, it is associated with Console Appender by default. We’ll see that in action shortly.

Let’s add logging statements of all Log Levels i.e. DEBUG < INFO < WARN < ERROR < FATAL. Add following lines of code inside main method so that they can be executed when our class is run.

1
2
3
4
5
logger.debug("Sample debug message");
logger.info("Sample info message");
logger.warn("Sample warn message");
logger.error("Sample error message");
logger.fatal("Sample fatal message");

As you can notice, Logger class’s object has provided us with methods, named same as logging level, thus simply passing a normal string to one of these methods, will set the log level of the statement.

Let’s execute our class at this point. Click on the Class Name, right click and select Run As > Java Application. Following error will be displayed on console.

1
2
3
log4j:WARN No appenders could be found for logger (root).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

The console output is detailed enough, and you can follow the link to read further. It suggests we need a configuration file, so that is what we will do next.

Step 3: Adding Properties file based Log4j Configuration

Log4j is very flexible on configurations. There are two ways we can configure a Log4j implementation, by either using a standard properties file named ‘log4j.properties’ or by using an xml based configuration file and naming it ‘log4j.xml’.

To start with, we’ll choose the simpler path and add a log4j.properties file to our project with minimum configurations required. Right click on the project name and create a new blank file and name it log4j.properties. It should be placed in root folder of our project.

Let’s configure our root logger inside log4j properties file. Add following key=value pair inside properties file.

1
log4j.rootLogger=DEBUG,SAWAN

What this line of configuration tells to log4j is two things, one it sets the Log Level of the Logger itself to DEBUG. Meaning, now logger will only display statements having DEBUG or high level (since DEBUG is at minimum level, thus it will display all. We’ll play with this later).

After the comma, SAWAN is the custom name of an appender, that we are telling to root logger, we will be configuring later in the properties configuration file. You can name it to anything.

So now let’s add that Appender we promised to root level Logger. Add following property

1
log4j.appender.SAWAN=org.apache.log4j.ConsoleAppender

This property, simply creates and configures the appender with our custom name. Value of this property is set to org.apache.log4j.ConsoleAppender thus this appender will print on Console. We have already associated it with root level logger in first statement so now root level Logger is able to display its logging statements on Console.

However there is still one piece of information that this Appender wants to know and that is, ‘How should I display the passed logging statement on Console”. Well that’s a valid question, so let’s tell our appender to relax and print in simplest possible format. For this add following line of configuration.

1
log4j.appender.SAWAN.layout=org.apache.log4j.SimpleLayout

in this line SAWAN.layout is set to SimpleLayout, provided by log4j package by default.

The configuration file should now look like:

1
2
3
log4j.rootLogger=DEBUG,SAWAN 
log4j.appender.SAWAN=org.apache.log4j.ConsoleAppender
log4j.appender.SAWAN.layout=org.apache.log4j.SimpleLayout

Let’s now execute our class. Right click on class name and select Run As > Java Application. Now you’ll see all our logging statements displayed on Console.

Output of basic logging statements

Fig 2-Output of basic logging statements


Wala! Our project is now Log4j enabled, and we can print as many log statements as we want, and configure them externally using properties file based configurations. From here, you will use same configuration file to enable any java class with logging capabilities.

Issue Resolution

If you have not faced any issue trying out this tutorial then you can skip this section. Some common issue(s) and their solutions reported by programmers following this tutorial are listed below

Problem: log4j:WARN No appenders could be found for logger (root). log4j:WARN Please initialize the log4j system properly.

Solution: This problem is most likely due to the location of the log4j.properties file. Try to place it in src folder and see if issue is resolved.

Download Tutorial Code:

Tutorial Working Code: Download

Note: Use File > Import option in Eclipse to import downloaded project source files.

Exercise:

  • Change the debug level of Root Logger to WARN. Execute the class and see how many log statements are now printed, are they greater than or less than WARN level.

  • Change the name of appender in configurations for the root logger. How many places do we need to change the Appender name?

  • Change the Appender layout to use org.apache.log4j.PatternLayout and add following pattern property at the end of properties file.

    1
    
    log4j.appender.SAWAN.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

    Did you notice any difference in layout of logging statements?

  • Add another appender to root logger, after SAWAN by inserting it at end as comma separated list. Name this Appender as ‘FILE’. Also add following lines of configurations to configure this FILE appender.

    1
    2
    3
    4
    5
    
    log4j.appender.FILE=org.apache.log4j.RollingFileAppender
    log4j.appender.FILE.File=helloworld.log
    log4j.appender.FILE.MaxFileSize=20480KB
    log4j.appender.FILE.MaxBackupIndex=5
    log4j.appender.FILE.layout=org.apache.log4j.SimpleLayout

    After executing class, were you able to locate a file named helloworld.log in root folder of project. (Refresh your workspace in eclipse). What are the output log statements in that file?

Project Locker & Git Integration using Secure Shell (SSH) & RSA

**adsense_4x1Block**
For a new project we recently started working on, we inherited existing code repository and source code management setup which included:

1. Project Locker as Free Git Repository Host
2. Git as Code Repository
3. TortoiseGit as Git UI
4. STS for development


In order to get started with development on project, we needed to integrate our Git Repository on Project Locker with local repository using TortoiseGit.

For enabling this integration and communication between these components, Secure Shell (SSH) protocol is used, which is based on RSA authentication. SSH protocol uses a Private-Public key pair to secure the connection thus we generated keys using process defined below and configured Project Locker & Git with our local repository. (more on SSH on WikiPedia)


Generating RSA Keys:

1. SpringSource Tools Suite > Preferences > General > Network Connections > SSH2 > Key Management
2. Press Generate RSA Key
3. Press Save Private Key (Click through the warning for Passpharase). Browse for the destination where you want to put the Private Key. Both private and public keys will be saved in selected folder. (id_rsa, id_rsa.pub)


Configuring Project Locker for Access:

1. Sign into your Project Locker account and select ‘Manage Public Keys’ under User Links on left menu.
2. Press New Key link at the bottom of table. Enter name for your machine, and Username in the format of @
3. Open id_rsa.pub file in notepad and copy paste its contents into Key field. Make sure there are no extra white spaces at the end of the content. Save Public Key


Generating Putty Formatted Private/Public Keys:

1. Download and Launch puttygen.exe.
2. Clik on Load button and browse to the id_rsa private key generated through STS above.
3. Click on Save private key button, which will save Putty formatted private key to your desired destination with *.ppk extension. Save public Key as well.


Configuring TortoiseGit for remote Repository:

1. Right click in the folder where you want to pull code from remote repository.
2. Select TortoiseGit > Settings from the context menu.
3. In Settings wizard, select Git > Remote settings. If you already have an origin (Default Git remote) then update otherwise create new. use settings below to configure your remote.

Remote: origin
Url: git-XXXXXX@pl3.projectlocker.com:XXXXXX.git //Url obtained from Project locker’s dashboard against Git repository
Putty Key: D:/Path to your private key generated through Putty


Hopefully these steps will guide you enough, however if you still have queries, feel free to post in comments.