Creating a Jar using Maven

In the earlier post, we had seen how to create a jar, in this post we will see how to create a jar using maven. Following are key points in creating the jar using maven.

1. Specify the packaging type e.g. jar.

2. Compile the source code. Use  maven-compiler-plugin here.

3. Generate eclipse related files like .classpath, etc. Use maven-eclipse-plugin. [optional]

4. Bundle the java class files in a jar. Use maven-jar-plugin.

5. Provide the main-class[entry point] for your jar in the mainfest.

6. Execute the unit-tests of your jar before creating the jar. [optional]

Refer to the sample pom.xml below:

<?xml version="1.0" encoding="UTF-8"?>
<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.schoudari.blog</groupId>
  <artifactId>my-blog-reader</artifactId>
  <packaging>jar</packaging> <!--1.Packaging Type -->
  <version>1.0.0-SNAPSHOT</version>
  <name>Blog Reader</name>

  <properties>   
    <log4j.version>1.2.16</log4j.version>
  </properties>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId> <!--2.Compiles the source-code -->
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId> <!--3.Generates the eclipse-related files -->
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId><!--4.Creates a jar -->
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>com.schoudari.blog.BlogReader</mainClass><!--5.Add main class -->
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId><!--6.Executes the unit-test cases -->
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>       
  </dependencies>  
</project>

Advertisements

Basics of Jar

A few years back, i was asked why a class in jar was not running as expected from command prompt. The answer was quite simple, the dependencies of the class are not available.

There is a common misconception that you create a jar and everything runs out of the box for you when you run the main class. Now what is the main class in the jar. Let me give you some introduction to jars:

a. Jar – Java archive. As the name says, it archives a set of java files.

b. Common Jar Operations

Operation Command
To create a JAR file jar cf jar-file input-file(s)
To view the contents of a JAR file jar tf jar-file
To extract the contents of a JAR file jar xf jar-file
To extract specific files from a JAR file jar xf jar-file archived-file(s)
To run an application packaged as a JAR file (requires the Main-class manifest header) java -jar app.jar

c. In general, a java file uses some or the other open source libraries e.g. log4j.jar, etc. Hence, when we create a jar, it is required that it is available in the class-path when we are creating the jar, so the class files can be created and then, they can be bundled. The same principles applies when you execute the jar file as well.

d. Every jar should have at-least one Main-class. Main-class is a class, which is a public class, with the public static void main(String[] args) method. This is the entry-point for all the classes in your jar. P.S. There can be more than one main class as well. In such a case, it is preferable not to have a main-class specified in the manifest.

e. A jar generally comes with a MAINFEST file. This is like meta-information about a jar. e.g.

Manifest-Version: 1.0
Main-Class: MyClass
Class-Path: MyUtils.jar
Created-By: 1.6.0 (Sun Microsystems Inc.)

Useful links:
http://docs.oracle.com/javase/tutorial/deployment/jar/index.html

Difficult Java interview questions – Serialization

This article is a follow-up to my article here

a. Are static variables serializable?

Ans: Static and transient variables of a class are not serializable. 

b. Can a class implement both Serializable and Externalizable?

Ans: Yes, the class can implement both Serializable and Externalizable.

c. What happens to the non-serializable objects in a class while serializing which implements Serializable?

Ans: The class fails to serialize with exception  java.io.NotSerializableException.

d. What happens to the non-serializable objects in a class while serializing which implements Serializable, Externalizable?

Ans: The class can be serialized and de-serialized successfully.

e. How do we deal with serialVersionUID when a class implements Serializable?

Ans:  If we don’t provide a serialVersionUID,  java compiler generates a serialVersionUID based on the properties defined in the class. Hence, if we have modified the class with a new property after a class has been serialized, then it will fail while de-serializing as a new serialVersionUID is generated by java compiler again. So, to get around this issue, we can fix the serialVersionUID of a class to be 1L. 

f. If we have a Serializable class “MyClass” which extends “MySuperClass”. What happens to the properties of “MySuperClass”, when we serialize/de-serialize “MyClass”?

Ans: If the properties inside the “MySuperClass” are serializable like primitives,serializable classes then all these will be available in the sub-class during/after serialization. However, if there are non-serializable properties, then there should be a default constructor in “MySuperClass” provided.

g. How do we serialize the non-serializable properties of a super-class[non-serializable] in a serializable sub-class?

Ans: We will have to over-ride the default private writeObject() and readObject() methods of sub-class and provide values for the non-serializable properties. Otherwise, ensure that the non-serializable properties are set with some default/specific values while creating the sub-class it-self. Refer below for sample code:

import java.io.*;

public class TestSerialization {
    public static void main(String args[]) {
        // Object serialization
        try {
            MyClass object1 = new MyClass("Hello");
            System.out.println("object1: " + object1);
            FileOutputStream fos = new FileOutputStream("serial");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(object1);
            oos.flush();
            oos.close();
        } catch (Exception e) {
            System.out.println("Exception during serialization: " + e);
            System.exit(0);
        }
        // Object deserialization
        try {
            MyClass object2;
            FileInputStream fis = new FileInputStream("serial");
            ObjectInputStream ois = new ObjectInputStream(fis);
            object2 = (MyClass) ois.readObject();
            ois.close();
            System.out.println("object2: " + object2);
        } catch (Exception e) {
            System.out.println("Exception during deserialization: " + e);
            System.exit(0);
        }
    }
}

class FailSerilization{
    String y="fail serilization";
}

class MySuperClass{
    String x="not super";
    FailSerilization fs;

//    MySuperClass(FailSerilization fs){
//        this.fs=fs;
//    }
    MySuperClass(){
        fs=new FailSerilization();
    }

}

class MyClass extends MySuperClass implements Serializable {
    String s;

    public MyClass(String s) {
        //super(new FailSerilization());
        this.s = s;

    }

    public String toString() {
        return "s=" + s + ";x= "+x+"; fs= "+fs.y;
    }
}

More here:

class MyClass extends MyClass2 implements Serializable{

  public MyClass(int quantity) {
    setNonSerializableProperty(new NonSerializableClass(quantity));
  }

  private void writeObject(java.io.ObjectOutputStream out)
  throws IOException{
    // note, here we don't need out.defaultWriteObject(); because
    // MyClass has no other state to serialize
    out.writeInt(super.getNonSerializableProperty().getQuantity());
  }

  private void readObject(java.io.ObjectInputStream in)
  throws IOException {
    // note, here we don't need in.defaultReadObject();
    // because MyClass has no other state to deserialize
    super.setNonSerializableProperty(new NonSerializableClass(in.readInt()));
  }
}

/* this class must have no-arg constructor accessible to MyClass */
class MyClass2 {

  /* this property must be gettable/settable by MyClass.  It cannot be final, therefore. */
  private NonSerializableClass nonSerializableProperty;

  public void setNonSerializableProperty(NonSerializableClass nonSerializableProperty) {
    this.nonSerializableProperty = nonSerializableProperty;
  }

  public NonSerializableClass getNonSerializableProperty() {
    return nonSerializableProperty;
  }
}

class NonSerializableClass{

  private final int quantity;

  public NonSerializableClass(int quantity){
    this.quantity = quantity;
  }

  public int getQuantity() {
    return quantity;
  }
}

Upload multiple files in Spring MVC 3

It was just another long day at office with the database not available and one of the team members lagging by a week now. So, we had to work as a team to get it delivered. In Spring 3, it looked straight forward to upload a file. However, there was little help on offer, to upload multiple files from a jsp file.

There are three basic things which need to be done to upload multiple files are:

a) The JSP needs to have the input[file] elements passed as an array.

<td><input name="fileData[0]" id="image0" type="file" /></td>
<td><input name="fileData[1]" id="image1" type="file" /></td>

b) The ModelAttribute/Model object in Spring MVC needs to have a list of MultipartFile.

import java.util.List;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
public class UploadItem {
     private String filename;
     private List<CommonsMultipartFile> fileData;

c) Configure Multipart Resolver bean in dispatcher-servlet.xml[applicationContext-servlet.xml]

<!-- Configure the multipart resolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

d) Logic to read the files from the Model and store it in a file location in the Controller layer.

@RequestMapping(method = RequestMethod.POST)
public String create(UploadItem uploadItem, BindingResult result,
HttpServletRequest request, HttpServletResponse response,
HttpSession session) {
if (result.hasErrors()) {
for (ObjectError error : result.getAllErrors()) {
System.err.println("Error: " + error.getCode() + " - "
+ error.getDefaultMessage());
}
return "/uploadfile";
}
// Some type of file processing...
System.err.println("-------------------------------------------");
try {
for(MultipartFile file:uploadItem.getFileData()){
String fileName = null;
InputStream inputStream = null;
OutputStream outputStream = null;
if (file.getSize() > 0) {
inputStream = file.getInputStream();
if (file.getSize() > 20000) {
System.out.println("File Size exceeded:::" + file.getSize());
return "/uploadfile";
}
System.out.println("size::" + file.getSize());
fileName = request.getRealPath("") + "/images/"
+ file.getOriginalFilename();
outputStream = new FileOutputStream(fileName);
System.out.println("fileName:" + file.getOriginalFilename());
int readBytes = 0;
byte[] buffer = new byte[10000];
while ((readBytes = inputStream.read(buffer, 0, 10000)) != -1) {
outputStream.write(buffer, 0, readBytes);
}
outputStream.close();
inputStream.close();
// ..........................................
session.setAttribute("uploadFile", file.getOriginalFilename());
}
//MultipartFile file = uploadItem.getFileData();
}
} catch (Exception e) {
e.printStackTrace();
}
return "redirect:/forms/uploadfileindex";
}

I have extended the example which is found @ RoseIndia to dynamically create the file nodes and post them to the Controller.

Just download the source-code and replace the below jsp file and make other necessary changes:

Upload.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page pageEncoding="UTF-8"%>
<%@ page session="false"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<html>
<head>
<META http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Upload Example</title>
<script language="JavaScript">
var count=0;
function add(type) {
//Create an input type dynamically.
var table = document.getElementById("fileUploadTable");
var tr = document.createElement("tr");
var td = document.createElement("td");
var element = document.createElement("input");

//Assign different attributes to the element.
element.setAttribute("type", "file");
element.setAttribute("value", "");
element.setAttribute("name", "fileData["+type+"]");
//Append the element in page (in span).
td.appendChild(element);
tr.appendChild(td);
table.appendChild(tr);
}
function Validate()
{
var image =document.getElementById("image").value;
if(image!=''){
var checkimg = image.toLowerCase();
if (!checkimg.match(/(\.jpg|\.png|\.JPG|\.PNG|\.jpeg|\.JPEG)$/)){
alert("Please enter Image File Extensions .jpg,.png,.jpeg");
document.getElementById("image").focus();
return false;
}
}
return true;
}

</script>
</head>
<body>
<form:form modelAttribute="uploadItem" name="frm" method="post"
enctype="multipart/form-data" onSubmit="return Validate();">
<fieldset><legend>Upload File</legend>
<table >
<tr>
<input type="button" name="Add Image" onclick="add(count++)" value="Add Image"/>
</tr>
<tr>
<table id="fileUploadTable">
<!--td><form:label for="fileData" path="fileData">File</form:label><br />
</td>
<td><input name="fileData[0]" id="image0" type="file" /></td>
<td><input name="fileData[1]" id="image1" type="file" /></td-->
</table>
</tr>
<tr>
<td><br />
</td>
<td><input type="submit" value="Upload" /></td>
</tr>
</table>
</fieldset>
</form:form>
</body>
</html>

UploadItem.java

Generate getter and setter methods for the private List fileData;

UploadFileController.java

Just copy and paste the create(…) mentioned in the blog above.

Note: If you are still facing issue with file upload in Spring MVC, please add a MultipartFilter. Refer here.

<filter>
<filter-name>multipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>multipartFilter</filter-name>
<url-pattern>/springrest/*</url-pattern>
</filter-mapping>
<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>10000000</value>
</property>
</bean>

Proxy objects in Spring are not evil

Firstly, let me give some back-ground about Spring Transaction Management. Spring uses Proxies for transaction management and these proxies are JDK dynamic proxies. However, Spring uses CGLIB proxies when a bean class doesn’t implement an interface. A point to note, proxy as such delegates control to a transaction manager to manage transactions.

To understand how proxies are used in Spring, refer to Micheal Isvy’s blog.

A month ago, i was discussing with a colleague about the performance problems with proxying which is used left, right and center in Spring’s transaction management and other features. As i am a strong supporter of Spring, i couldn’t agree but at the same time couldn’t disagree with him. However, i am ready to take a stand now:

a. Proxies do add a performance over-head. A direct call to a method in target object always takes less time than a call through a proxy object.  However, it is negligible compared to the benefits we reap out of a ready-to-use features without having to worry about writing code to do it.

b. The advice above, needs to be taken with a pinch of salt, though. Too much proxying results in performance problems. A better solution in such a situation would be to perform byte code weaving using AspectJ. This is achieved by using JavaAgent.

Courtesy: Alef Arendenson

 

Serialization issue with Quartz and Postgres

I was using Quartz 1.6.x.jar, postgresql-8.4.x.jar with Postgresql 9.1 database in my application. Though my application started properly, there were exceptions in the log, as mentioned below:

org.quartz.JobPersistenceException: Couldn’t store trigger: invalid stream header: BB656430

It was more of a compatibility issue  with quartz and older postgresql drivers with latest Postgresql 9.1 database. My suspicion was proven when i referred to this blog  (by Timmy Jose) and followed its advice.

You can download the latest postgresql jdbc driver from here.

Effective Logging in Java/JEE

It all started when i was sitting with a colleague to resolve some application issue, when i noticed something interesting. He was merging the code and my eyes caught the attention of this class “org.apache.log4j.MDC”. This led to few discoveries on the way which  follow here:

What is MDC?

MDC stands for Mapped Diagnostic Context. It helps you to distinguish inter-leaving logs from multiple sources. Let me explain in detail. When we have multiple user-requests coming in for a given servlet, each request of an user is serviced using a thread. This leaves multiple users logging to the same log file and the log statements get inter-mixed. Now, to filter out logs of a particular user, we need to append the user-id to the log statements so that we can grep(search) them in the log file, to make some sense of it.

An obvious way of logging, is to append the user-id in the log statements i.e. log.info(userId+” logged something “);

A non-invasive way of logging is to use MDC. With MDC, you put the user-id in a context-map which is attached to the thread (of each user request) by the logger.

MDC is thread-safe and uses a Map internally to store the context information.[Courtesy : Kalyan Dabburi]

How to use MDC?

a. Configure the information, which needs to be logged (user-id in this case) in the log4j.xml as part of ConversionPattern.

log4j.appender.consoleAppender.layout.ConversionPattern 
= %d %i - %m - %X{user-id}%n

b. In your respective class, before you start processing the user request, place the actual user-id in the context(MDC).

MDC.put("user-id","SKRS786");

c. Remove the context information from MDC at the end of the processing.

MDC.remove("user-id");

References :

Logback implementation

Log4J implementation

 

What is NDC ? Which one to use MDC or NDC?

NDC stands for Nested Diagnostic Context. It is a stack-based implementation of attaching context information. For all purposes, use MDC over NDC, as MDC is memory efficient. For a detailed comparison, click here.

Which logging framework to use? Log4J or SLF4J or logback?

For all new application development, use logback. logback is a run-time implementation of SLF4J. If you have an existing application with Log4J, it is still worth-while to switch to logback. For a detailed explanation, click here.

To understand the evolution of logging in Java and JEE world, refer to this article by Micheal Andrews.