Sunday 3 August 2008

Java abstract enumeration and java.lang.Class.isEnum() problem

One of new features in Java 1.5 is direct support of enumeration using enum keyword. According to this the new method isEnum() has been added to java.lang.Class class (which is part of Java Reflections API). The problem is that the isEnum method doesn’t always behave as you would expect.

Let’s start with the following Java code:

public class MainTest {

// Enum with custom constructor
enum EnumPrivate {

VALUE(1);

private int value;

private EnumPrivate(int value) {
this.value = value;
}

public int getValue() {
return value;
}

}

// Enum having an abstract method
enum EnumAbstract {

VALUE(1) {
public int getRandomValue() {
return 10;
}
};

private int value;

private EnumAbstract(int value) {
this.value = value;
}

public abstract int getRandomValue();

}


/**
* @param args
*/
public static void main(String[] args) {
System.out.println(EnumPrivate.VALUE.getClass().isEnum());
System.out.println(EnumAbstract.VALUE.getClass().isEnum());
}

}


Both EnumPrivate and EnumAbstract are not simple enums. The first one has custom constructor (which must be private) and the second an abstract method which must be implemented in each enum’s value. Let’s try to run the main method. You would probably expect “true” twice in the output but you will get the “true” and “false”. It’s quite strange isn’t it?

Let’s try to find out what the java.lang.Class documentation says about isEnum() method. You would find the following:

Returns true if and only if this class was declared as an enum in the source code.

The description of the method doesn’t say anything special about enums with abstract methods so let’s find the isEnum method’s source code in JDK. You could find the following:

public boolean isEnum() {
return (this.getModifiers() & ENUM) != 0 &&
this.getSuperclass() == java.lang.Enum.class;
}


You can see that isEnum returns true if the super class of the class represeting an enum is java.lang.Enum class (we will not bother about modifier) but what's the supeclass of the our enum class? How to find out? The answer is that they are compiled to ordinary Java classes in the same way as any other class so let’s try to decompile them. You would get the result similar to the following:

final class EnumPrivate extends Enum
{

public static final EnumPrivate VALUE;
private int value;
private static final EnumPrivate ENUM_VALUES[];

static
{
VALUE = new EnumPrivate("VALUE", 0, 1);
ENUM_VALUES = (new EnumPrivate[] {
VALUE
});
}

private EnumPrivate(String s, int i, int value)
{
super(s, i);
this.value = value;
}



}

abstract class EnumAbstract extends Enum
{

public static final EnumAbstract VALUE;
private int value;
private static final EnumAbstract ENUM_VALUES[];

static
{
VALUE = new EnumAbstract("VALUE", 0, 1) {

public int getRandomValue()
{
return 10;
}

};
ENUM_VALUES = (new EnumAbstract[] {
VALUE
});
}

private EnumAbstract(String s, int i, int value)
{
super(s, i);
this.value = value;
}

public abstract int getRandomValue();

EnumAbstract(String s, int i, int j, EnumAbstract EnumAbstract)
{
this(s, i, j);
}

….

}


If you compare EnumPrivate and EnumAbstract then you should find the problem. EnumPrivate extends the Enum and it’s VALUE is EnumPrivate. EnumAbstract extends Enum as well but because it has the abstract method it must be the abstract class. VALUE is then anonymous inner child class of the EnumAbstract so its superclass is not Enum but EnumAbstract!

As you can see enums (or isEnum) should be corrected a bit in the future versions of Java. You have got two enumerations according to specification but only one of them is correctly recognized as enumeration.

You can find many issues when using enums with abstract methods in combination with third party libraries (or applications). Assume a library for automatic converting standard Java types to e.g. String. The library will get the Object and then need to find out the type of object to correctly do the conversion to String. If the library relies on the isEnum() method to recognize enums then it won’t correctly recognize your enum with abstract method value as enum. This happened to me and I spend a few hours searching for the problem and that’s the reason why I decided to share my experience with you.

Monday 30 June 2008

State design pattern in Java

State design pattern is extremely useful when you need a state class. Typical example is a class making a connection to a server (check POP3 client tutorial for example). The class then has two states – connected and disconnected (which is the default state). In the class you would need to check for the state at many places. Let’s imagine that your class doesn’t have just two states but four or ten. You would find then many constructs similar to the following in your class:

public class Door {

private DoorStates state;

private void someMethod() {
// ....
switch (state) {
case CLOSED: // .....
case CLOSING: // .....
case OPENED: // .....
case OPENING: // .....
}
// ...
}

}


The main reasons for State design pattern are extensibility and simplification of the code.

Now I would like to tell you how to implement State designer pattern. The first thing you need to do is to figure out states which your class (let’s call it main class) can have. Let’s have a class handling a connection to a server. The class can certainly have states connected and disconnected. Each state is implemented using its own class (let’s call it state class) and all state classes have one identical ancestor (either interface or abstract class). In state class would be methods that behave differently in each state (the methods that would contain switch (state) { … } ). At first let’s see the main class:

public class Connection {

// state class instance reference
private ConnectionState state;

// list of all possible states
protected final ConnectionState CONNECTED = new ConnectionStateConnected(this);
protected final ConnectionState DISCONNECTED = new ConnectionStateDisconnected(this);

public Connection() {
// default state is disconnected
state = DISCONNECTED;
}

public void connect() {
state.connect();
}

public void disconnect() {
state.disconnect();
}

public boolean isConnected() {
return state.isConnected();
}

// called by a state class to set new state to this connection
protected void setState(ConnectionState state) {
this.state = state;
}

}


The first in the class is the state attribute that holds the actual state of the main class. Next attributes CONNECTED and DISCONNECTED are all possible states that the class can have. Please notice that they are protected. That is because of the state classes which need access them as you will see later. All state methods just delegate the call to the state class.

Now let’s see the ancestor of the all state classes:

public abstract class ConnectionState {

// childs need to have access to the connection instance too
protected final Connection connection;

public ConnectionState(Connection connection) {
this.connection = connection;
}

public abstract void connect();

public abstract void disconnect();

public abstract boolean isConnected();

}


Each state class has to implement the abstract class above. The only interesting thing is the connection attribute. A state class usually need somehow change state of the main class thus it has a main class reference so that the setState(…) method can be called in a state class.

I said that the connection class would have two states – connected and disconnected. We would then have two implementations of the abstract state class named ConnectionStateConnected and ConnectionStateDisconnected.

public class ConnectionStateConnected extends ConnectionState {

public ConnectionStateConnected(Connection connection) {
super(connection);
}

public void connect() {
throw new IllegalStateException("Already connected");
}

public void disconnect() {
// disconnect somehow

// finally set disconnected state of the connection instance
connection.setState(connection.DISCONNECTED);
}

public boolean isConnected() {
return true;
}

}


Please notice how the state class changes the state of the main class in disconnect() method.

public class ConnectionStateDisconnected extends ConnectionState {

public ConnectionStateDisconnected(Connection connection) {
super(connection);
}

public void connect() {
// connect somehow ...

// finally set connected state of the connection instance
connection.setState(connection.CONNECTED);
}

public void disconnect() {
throw new IllegalStateException("Already disconnected");
}

public boolean isConnected() {
return false;
}

}


You have to carefully figure out what to do if a state is called but it shouldn’t be. Example can be calling disconnect() method when there is no connection. You can either throw IllegalStateException or just log warning message wherever.

As you can notice … adding a new state is very simple task. You just add new child of the abstract state class, add new attribute representing the new state to the main class and that’s all.

You can download source codes here: http://rapidshare.com/files/126155409/stateDesignPattern.zip

Sunday 8 June 2008

How to call private constructor/method from outside in Java

As you certainly know, one of the OOP’s features is encapsulation. Java has private keyword to specify encapsulated constructors, methods or attributes. These methods and attributes should not be accessible from the rest of the world (they are not part of the API) and Java doesn’t allow you to do that ordinarily.

You can however use Java reflections API to access any private method, field or constructor of any class and it’s really very simple task. Let’s assume we have got the following simple class:
public class Test {

private Test() {
System.out.println("private constructor has been called");
}

private void test() {
System.out.println("private test() method has been called");
}

}
The class has private constructor and method (notice that such class is worthless because there is no way how to ordinarily get or create instance of it). Now I’ll show you how to get instance of the class using Java reflections and call the private method:
public class Main {

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException, SecurityException, NoSuchMethodException {

Class<Test> clazz = Test.class;

Constructor<Test> c = clazz.getDeclaredConstructor((Class[])null);
c.setAccessible(true); //hack
Test test = c.newInstance((Object[])null);

Method privateMethod = clazz.getDeclaredMethod("test", (Class[])null);
privateMethod.setAccessible(true); //hack
privateMethod.invoke(test, (Object[])null);
}

}
If you hadn’t called the setAccessible(true) method you would have got the java.lang.IllegalAccessException indicating that you call a method/constructor which is not meant to be called from outside.

Java reflections breaks OOP in many ways and you should very rarely use its “special” features like accessing private methods in your projects.

Monday 19 May 2008

Java enum in Java Native Interface (JNI)

A few days ago I started to take interest in JNI (http://en.wikipedia.org/wiki/Java_Native_Interface). JNI is used to call java native methods that are written in other language than Java. Java native methods are usually system dependent and are used to provide functionality that has to be handled by an operating system. Example is creating and handling threads in Java. This functionality is system dependent and has to be handled directly by an operating system (let’s try to open and go through java.lang.Thread class source code in JDK). You can find very useful specification of JNI containing a few examples at http://java.sun.com/j2se/1.5.0/docs/guide/jni/. JNI provides many methods for manipulating Java primitive types, objects, exceptions, non-native methods and so long, but what is missing in the JNI guide is description how to manipulate enums in native code (implemented using e.g. C++) and that’s what I’m going to show you here (using C++).

Let’s assume we have got the following simple enum:

package test;

public enum MyEnum {
VALUE1, VALUE2, VALUE3;
}


Since Java version 1.5 enums are converted to ordinary Java classes so treat them is similar to any other Java object (I recommend you to decompile compiled MyEnum.class file). For the following native method declaration:

package test;

public class SomeClass {
public native String enumTest(MyEnum myEnum);
}


is then, using javah generator (it’s part of JDK, not just JRE), generated following C header:
JNIEXPORT jstring JNICALL Java_test_SomeClass_ enumTest(JNIEnv *, jobject, jobject);
The first parameter is pointer to Java environment, second is Java the object on which is the native method called and the third is the myEnum parameter (notice that the type is object). The way how to handle object in native code is a little bit similar to the Java reflections.

The first thing you have to do is to find the name of the method that returns actual "value" of the enum. You can find in the documentation (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Enum.html) that every enum has (among others) method name() that returns name of the value of the enum as String (the second usable method is ordinal() ). Now I’m going to show you how to call the name() method in native code implemented using C++:
JNIEXPORT jstring JNICALL Java_test_SomeClass_ enumTest(JNIEnv *env, jobject obj, jobject enumObj) {
jclass enumClass = env->FindClass("test/MyEnum");
jmethodID getNameMethod = env->GetMethodID(enumClass, "name", "()Ljava/lang/String;");
jstring value = (jstring)env->CallObjectMethod(enumObj, getNameMethod);
const char* valueNative = env->GetStringUTFChars(value, 0);
if (strcmp(valueNative, "VALUE1") == 0) {
printf("Enum has the VALUE1 value");
}
// ...
return NULL;
}
On the first line the pointer to the class is obtained using FindClass (http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp16027) method. You should notice that package name is delimited by "/" and not by ".". On the second line the pointer to the correct method - name() is obtained using GetMethodID (http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp16660) method. You have to provide correct method’s signature (look into the specification how to get correct method’s signature). The third line calls the method against given object. CallObjectMethod (http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp4256) means that the method itself returns object (String). The fourth line converts returned string value from UTF-8 (which is used as encoding of strings in Java) to C encoding and finally the last line just compares obtained valued against one of the enum’s values.

Saturday 26 April 2008

(Synchronized) Singleton design pattern in Java

Singleton falls into the group of simple design patterns. Singleton is a class that has one and only instance in an application. As singletons are usually realized pools (connection, thread, …), cash memories or drivers.

Implementing singleton is quite simple task. The following steps have to be done:
  • declare constructor as private to ensure that no instance of the class can be created
  • implement public static method that returns the only instance of the class
Demonstration of the simple singleton follows:
public final class SimpleSingleton {

private static final SimpleSingleton theInstance = new SimpleSingleton();

private String textAttribute;

private SimpleSingleton() {
textAttribute = "Some text";
}

public static SimpleSingleton getInstance() {
return theInstance;
}

public String getText() {
return textAttribute;
}

}

Because the private constructor, no descendant of the class can be made, so it’s useful practice to declare the singleton class as final to indicate that.

In the example above you can see that instance of the singleton is initialized in the same moment when the class is initialized. If the initialization of the singleton is quite timely-consuming task or it’s not even known whether the singleton would be used then it’s useful to put the initialization off to the first moment when the singleton is needed. Demonstration follows:
public final class LazyInitializationSingleThreaded {

private static LazyInitializationSingleThreaded theInstance;

private LazyInitializationSingleThreaded() {
}

public LazyInitializationSingleThreaded getInstance() {
if (theInstance == null) {
// the dangerous line follows
theInstance = new LazyInitializationSingleThreaded();
}
return theInstance;
}

}

The above example can be safely used only in single threaded application. Because there is no synchronization of the code where the singleton is initialized, it can easily happen that two or more threads would enter the dangerous line. One solution is to synchronize whole method getInstance(), but then the synchronization check would be done whenever the method is called so that the performance would be quite low. The right solution is to synchronize only section where the instance is being initialized. Demonstration follows:
public final class LazyInitializationMultiThreaded {

private volatile static LazyInitializationMultiThreaded theInstance;

private LazyInitializationMultiThreaded() {
}

public static LazyInitializationMultiThreaded getInstance() {
if (theInstance == null) {
synchronized (LazyInitializationMultiThreaded.class) {
if (theInstance == null) {
theInstance = new LazyInitializationMultiThreaded();
}
}
}
return theInstance;
}

}

Keep in mind that singletons should not be serialized, because by de-serialization you get another instance of the singleton.

The last and more complicated case is when the singleton is defined as abstract class with descendants and the singleton while being initialized chooses the right descendant. This is useful when you need to have more singletons of the single type with different behavior. Demonstration follows:
public abstract class SingletonInheritance {

private static class CheerfulSingleton extends SingletonInheritance {};
private static class SadSingleton extends SingletonInheritance {};
private static class DefaultSingleton extends SingletonInheritance {};

private static SingletonInheritance theInstance;

public static SingletonInheritance getInstance() {
if (theInstance == null) {
synchronized (SingletonInheritance.class) {
if (theInstance == null) {
String mood = System.getenv("MOOD");
if (mood == null) {
mood = "";
}
theInstance = chooseInstance(mood);
}
}
}
return theInstance;
}

private static SingletonInheritance chooseInstance(String mood) {
if (mood.equalsIgnoreCase( "CHEERFUL" ))
return new CheerfulSingleton();
else if (mood.equalsIgnoreCase( "SAD" ))
return new SadSingleton();
else
return new DefaultSingleton();
}

private SingletonInheritance() {
}

}

Monday 24 March 2008

Java 6 compiler API tutorial

One of the new features in Java 6 is compiler API. It let’s you compile any Java source code file on the fly and after compilation you can load compiled class using a class loader and start using it. Because Java compiler doesn’t know anything about classes compiled on the fly, so you can use them only using java reflections.

In the first step we need to prepare a class that is going to be compiled using Compiler API. I prepared the following simple class:

package com.blogspot.mike_java;

public class ToBeCompiled {

public void callMe() {
System.out.println("Method callMe has been called");
}

}

And saved it to the directory “d:\javafiles\src” (absolute path to the ToBeCompiled.java file is “d:\javafiles\src\com\blogspot\mike_java\ ToBeCompiled.java”) and prepared directory for compiled files “d:\javafiles\bin”. The next step is to prepare a class that compiles ToBeCompiled class, loads it and runs method callMe() on an instance of it. I prepared in my favorite IDE Eclipse following class:

package com.blogspot.mike_java;

public class CompilerAPITest {

public static void main(String[] args) {
// source code is going to be here
}
}


All following source code lines will be in the main method of the CompilerAPITest class.

At first we need to get instance of JavaCompiler and StandardJavaFileManager:

JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager sjfm = jc.getStandardFileManager(null, null, null);


The next step is to get Iterable collection of files to be compiled and prepare options for compiler (you can find list of compiler options at http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html):

File javaFile = new File("d:/javafiles/src/com/blogspot/mike_java/ToBeCompiled.java");
Iterable fileObjects = sjfm.getJavaFileObjects(javaFile);
String[] options = new String[]{"-d", "d:/javafiles/bin"};


The next step is to compile Iterable collection of java files and close file manager:

jc.getTask(null, null, null, Arrays.asList(options), null, fileObjects).call();
sjfm.close();
System.out.println("Class has been successfully compiled");


After this step all compiled classes would be saved in directory “d:\javafiles\bin”. The next step is to load compiled class using class loader and run method callMe. At first we need to load compiled class:

URL[] urls = new URL[]{ new URL("file://d:/javafiles/bin/") };
URLClassLoader ucl = new URLClassLoader(urls);
Class clazz = ucl.loadClass("com.blogspot.mike_java.ToBeCompiled");
System.out.println("Class has been successfully loaded");


And get the method callMe using reflections:

Method method = clazz.getDeclaredMethod("callMe", null);


Finally we need to create new instance of the just loaded class and call method callMe on it:

Object object = clazz.newInstance();
method.invoke(object, null);


You can download source codes at http://rapidshare.com/files/102030988/compiler_api.zip. I hope that this tutorial was useful for you.

Tuesday 11 March 2008

Simple POP3 client in Java (tutorial)

This article is intended for people who have no or very little experience with networking in Java.

Today, my aim is to show you how to make your own simple POP3 client in Java. Some people are scared of creating a network application in Java because they think it have to be difficult to handle such topic, but opposite is true. It’s easier than you could think as you will see later. I chose the POP3, which is used to access your mailbox on a server, because it’s quite simple protocol. It has just a few commands. We are not going to implement all of them of course, just a few.

Before creating a first class in Java, let’s see the RFC 1939 specification of the POP3 protocol that can be found at http://www.faqs.org/rfcs/rfc1939.html. It’s always important to go through a specification of a protocol you are going to implement and to understand it well. You should read paragraph “3. Basic operation” where you would find information about default port for POP3 protocol (110) and two possible responses for any POP3 command: -OK indicating success and –ERR indicating a problem on the server. By the way response from the server can be multi-line (typically when server sends an email content) or single-line (e.g. response for command “USER”).

Now, when you are familiar with basic protocol operation we can start and create a first Java class, let’s give it name ‘POP3Client’. What fields would the class need to have? Firstly an instance of Socket (java.net.Socket) class for network communication and secondly reader as well as writer for receiving and sending network data. That’s could be enough, but for debugging feature let’s add boolean debug field and POP3’s default port value field. You should have something similar to the following:

public class POP3Client {

private Socket socket;

private boolean debug = false;

private BufferedReader reader;
private BufferedWriter writer;

private static final int DEFAULT_PORT = 110;

public boolean isDebug() {
return debug;
}

public void setDebug(boolean debug) {
this.debug = debug;
}
}


For simplicity I won’t deal with exceptions and state (with exception of connection establishment) below. You should have on mind that POP3 is state protocol and you should always check for the state before trying to do anything (e.g. client can’t logout from the server while not connected). The first method would handle connecting to the server and initializing needed fields. Let’s name the method connect(…) and implement it:

public void connect(String host, int port) throws IOException {
socket = new Socket();
socket.connect(new InetSocketAddress(host, port));
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
if (debug)
System.out.println("Connected to the host");
}


The first line creates new socket, the second connects it to the specified host and address, the third and fourth sets reader and writer and the last prints debug message. Let’s create second method that would use the DEFAULT_PORT field

public void connect(String host) throws IOException {
connect(host, DEFAULT_PORT);
}


Once the socket is connected to the server, you would need to somehow check for establishment of connection before disconnecting. Let’s implement isConnected() method:

public boolean isConnected() {
return socket != null && socket.isConnected();
}


Now we can implement disconnect() method that would disconnect socket from the server:

public void disconnect() throws IOException {
if (!isConnected())
throw new IllegalStateException("Not connected to a host");
socket.close();
reader = null;
writer = null;
if (debug)
System.out.println("Disconnected from the host");
}


Implementation of the method is quite straightforward, so let’s move a bit. Now the most important part will take place. We need somehow to send commands to the server and receive response. For sending data will use “writer” and for receiving data “reader”. Sending data is simple as long as receiving. To send data to server, you just call writer’s write(…) method and to receive you just call reader’s readLine() method. Let’s create and implement method readResponseLine() that will read and return one line of data sent by the server:

protected String readResponseLine() throws IOException{
String response = reader.readLine();
if (debug) {
System.out.println("DEBUG [in] : " + response);
}
if (response.startsWith("-ERR"))
throw new RuntimeException("Server has returned an error: " + response.replaceFirst("-ERR ", ""));
return response;
}


The first line reads the line of text sent by the server, the second prints it while in debug mode and the third checks for an error according to RFC specification. When we have got the method for receiving data from server, we need the method for sending data – commands - to the server. Let’s name it sendCommand(…) and implement it:

protected String sendCommand(String command) throws IOException {
if (debug) {
System.out.println("DEBUG [out]: " + command);
}
writer.write(command + "\n");
writer.flush();
return readResponseLine();
}


The first line prints command being sent while in debug mode, the second sends it and the third flushes the socket’s buffer. It’s one of the most important things and you should never forget to do it. If you don’t flush the buffer then the data are held in it (until the buffer is full) and not sent to the server. The last line reads and returns server’s response to our command.

You should know from RFC specification that just after connecting to the server, the server sends welcome string (something like “+OK Hello, this is POP3 server v. 2.3.16.”), so you have to receive it. Let’s modify existing connect method:

public void connect(String host, int port) throws IOException {

readResponseLine();
}


The next thing we need to do is to add support for logging in and out from the server. Let’s create two methods - login(…) and logout() - and implement them:

public void login(String username, String password) throws IOException {
sendCommand("USER " + username);
sendCommand("PASS " + password);
}

public void logout() throws IOException {
sendCommand("QUIT");
}


You can find in the RFC specification that to login to the server you need to send the combination of commands USER and PASS. The USER command takes as an argument username to an email account (e.g. john.dow@myserver.com) and PASS command takes as an argument the password. To logout from the server you need to send QUIT command. Once a user is logged to the server he can start manipulating his email messages. Firstly let’s create a method that will check for number of messages on the server:

public int getNumberOfNewMessages() throws IOException {
String response = sendCommand("STAT");
String[] values = response.split(" ");
return Integer.parseInt(values[1]);
}


I chose the STAT command (there’s also LIST command) that returns number of messages and theirs overall size in bytes (response has format: “+OK nn mm”, where nn is the number of messages and mm the size of messages in bytes). Now it’s the right time to prepare class for holding a message so let’s create it:

public class Message {

private final Map<String, List<String>> headers;

private final String body;

protected Message(Map<String, List<String>> headers, String body) {
this.headers = Collections.unmodifiableMap(headers);
this.body = body;
}

public Map<String, List<String>> getHeaders() {
return headers;
}

public String getBody() {
return body;
}

}


As you can suspect, every message has a list of headers (each header has a name and one or more values) and a body. The next method we are going to implement is method that gets a message from the server. Let’s name it getMessage(..):

protected Message getMessage(int i) throws IOException {
String response = sendCommand("RETR " + i);
Map<String, List
<String>> headers = new HashMap<String, List<String>>();
String headerName = null;
// process headers
while ((response = readResponseLine()).length() != 0) {
if (response.startsWith("\t")) {
continue; //no process of multiline headers
}
int colonPosition = response.indexOf(":");
headerName = response.substring(0, colonPosition);
String headerValue;
if (headerName.length()
> colonPosition) {
headerValue = response.substring(colonPosition + 2);
} else {
headerValue = "";
}
List
<String> headerValues = headers.get(headerName);
if (headerValues == null) {
headerValues = new ArrayList
<String>();
headers.put(headerName, headerValues);
}
headerValues.add(headerValue);
}
// process body
StringBuilder bodyBuilder = new StringBuilder();
while (!(response = readResponseLine()).equals(".")) {
bodyBuilder.append(response + "\n");
}
return new Message(headers, bodyBuilder.toString());
}


The method uses RETR command to get a message from the server. After sending the command, the server starts sending a message. Firstly headers terminated by empty line (its length is 0) followed by body terminated by line containing “.” character. The first loop goes through the all headers and saves it to the map “headers”. Each header is in the following format:

headerName: headerValue

The second loop goes through the all body response lines until the termination character is found. Finally the last method we are going to implement is method that will get complete list of messages from the server. Let’s name it getMessages():

public List
<Message> getMessages() throws IOException {
int numOfMessages = getNumberOfNewMessages();
List
<Message> messageList = new ArrayList<Message>();
for (int i = 1; i
<= numOfMessages; i++) {
messageList.add(getMessage(i));
}
return messageList;
}


I hope that it’s quite straightforward after all we did.

Now it’s the right time to test our implementation, let’s create some class and use the client in it:

public static void main(String[] args) throws IOException {
POP3Client client = new POP3Client();
client.setDebug(true);
client.connect("pop3.myserver.com");
client.login("name@myserver.com", "password");
System.out.println("Number of new emails: " + client.getNumberOfNewMessages());
List
<Message> messages = client.getMessages();
for (int index = 0; index
< messages.size(); index++) {
System.out.println("--- Message num. " + index + " ---");
System.out.println(messages.get(index).getBody());
}
client.logout();
client.disconnect();
}



Because the debug mode was turned on you should see a list of POP3 commands and its responses.

I hope that this tutorial was hopeful for you and that you enjoyed it as well as I did.

You can download source codes at http://rapidshare.com/files/100278017/pop3client.zip