Java

26
Dec

Creation of simple application in Java

Posted by eugene as Java

Good day!

This article is about the organization of the simple application in Java for beginners who has already learnt the concept of the object approach. But maybe it will be also interesting for the experienced developers.

The novice developers frequently ask the question: “How should I start creating the application”, which classes to use and so on.

You should not treat this article as an example of “Hellow World” for the beginners learning Java language and object-oriented approach. It is assumed that the reader is familiar with the language of Java however he would have questions above.

We give the answer to these questions in this article.

In order to build an application gradually, using the concepts of object-oriented approach, we will provide all the application elements in the form of the objects of the corresponding classes. Hence, the application will also be a separate class. In order to run the application, we’ll create an instance of it.

Now there’re some more details..

At first the Application class is created – it will be the model of the entire application.

public class Application {
}

Then let’s create the input point in the application – the main method:

public class Application {
    public static void main(String[] args) {
    }
}

This method is implemented when running Java specifying the basis class (Application). We create the application instance in it, initialize and then run it. We’ll use the init and run methods for this:

public class Application {
    public void init() {
    }
 
    public void run() {
    }
 
    public static void main(String[] args) {
        Application application = new Application();
        application.init();
        application.run();
    }
}

Let’s do the necessary application initialiazation in the init method. The main application code is located in the run method.

You may not use the init mehtod (it’s up to you), however we believe that our application has two stages – initialization and start.

All the other elements of the application can be divided into classes and types of the model (windows, panels). For example, suppose we create a simple credit calculator. The the CreditCalculator class will be the model of the calculator. We will initialize calculator in the init method and calculate in run:

public class Application {
    private CreditCalculator calculator;
 
    public void init() {
        calculator = new CreditCalculator();
    }
 
    public void run() {
        calculator.setAmount(500000);
        calculator.setYears(3);
        calculator.calculate();
        System.out.println("Месячный платеж: " + calculator.getMonthlyPayment());
    }
 
    public static void main(String[] args) {
        Application application = new Application();
        application.init();
        application.run();
    }
}

Thus, the creation of the application can be started with the creation of the Application class and then adding all the necessary model classes with which you want to work.

Now, how to start the application

We will proceed out of that you use the Eclipse development environment, Intellij IDEA or NetBeans. And the Application class is created in it. In these environments you should invoke the context menu and click Run… or Run As Application in the editor of the Application class.

But still the same – launching application from the environment was not our goal, and the goal was to understand with which classes you can start building applications.

The article is written based on the Procode podcast

RSS: procode.podomatic.com/rss2.xml

iTunes: itunes.apple.com/ru/podcast/procode/id529972125

The appeal to the cool developers is not swear – you know everything! But better swear – then it will be clear what is wrong.

The appeal is to leave the constructive comment before the assessment of the article.

22
Dec

Installing Oracle JDK 7 in Ubuntu 12.04

Posted by eugene as Java

Welcome to all the updated and those who just plans.

As many of you know proprietary Java was compiled from the offcial repositories. In return, the users were suggested to use OpenJDK. However there are serious problems with the stability of work of the last one. But let’s talk in order about all things….

Today, having installed new proxmox 2.1 on the server, I’ve found that the KVM console doesn’t work after the update of my system. I’ve quickly realized that it’s necessary to set up jre and I’ve looked into the terminal and installed openjdk-6-jdk with icedtea-6-plugin for the work of applets.

I restart the browser, go to the web side of proxmox, run the console. That’s all for it, more precisely the dancing just started as here is the incomplete list of problems which I coped with by using as openjdk-6-jdk, so and openjdk-7-jdk:
1) When closing the console window, Firefox falls at all with it.
2) The initialization of the applet with 100% load of CPU at the time the browser is blocked. It continues for quite a long time, which is very enraging.
3) Lots of pop-up proxmox errors.

It’s necessary to confess this is my first experience of working with OpenJDK and probably the last. Finally, I’ve decided to install the propriatery Java and started terrorizing Google, tell everybody how to do this with the minimal loss.

I’ve been almost happy but not for a long time. After that I’ve followed all the steps till the sudo apt-get install point, apt returned me the “Errors were encountered while processing: oracle-java7-installer” alert. And then again I’ve started searching in Google and found how to resolve it. In case someone was caught, I give you the link with cures of this desease.

I was desparate to find a solution in the web, hence I decided to follow the other way – the proved one. By simple manipulations, I’ve managed to make it work, the results pleasantly surprised me. In particular, the problems with the performance and browser crashing have disappeared.

Substance

Hence, we have two variants of that how to do install leaving the system clean. Before you will start, I recommend you to clear the system from OpenJDK:

sudo apt-get purge openjdk*

This command will clear everything what has the relation to all OpenJDK versions.

Method number 1.

Short and quick variant (if you have x86_64), where the .deb package is prepared before by me, put in the network, and you just need to download and install it:
1) Download the package.
2) Run the commands in terminal 4:

# It's necessary to run the transfer (cd command) beforehand into the directory,
# where the download of the .rpm package has been performed
sudo dpkg -i jdk_1.7.004-1_amd64.deb
mkdir -p ~/.mozilla/plugins
ln -s /usr/java/jdk1.7.0_04/jre/lib/amd64/libjavaplugin_jni.so ~/.mozilla/plugins/
ln -s /usr/java/jdk1.7.0_04/jre/lib/amd64/libnpjp2.so ~/.mozilla/plugins/

3) Restart the browser and have fun, also you’ve saved the time.
Of course, if you have 64-bit version of pangolin.

Method number 2, from the start to the end.

1) Go to the Java SE download website and download the (.rpm) package, according to our architecture:
Linux x86 (32-bit)
Linux x64 (64-bit)
2) Install alien, basically this is the package converter which will re-pack the downloaded .rpm packages in the required .deb extension with its own tricks.

sudo apt-get install alien

3) Incite the “alien” to the downloaded rpm.

sudo alien jdk-7u4-linux-x64.rpm --scripts

At this stage, the .deb package will be generated in the same directory.
4) Then install the package, create symlinks and enjoy your life.

sudo dpkg -i jdk_1.7.004-1_amd64.deb
mkdir -p ~/.mozilla/plugins
ln -s /usr/java/jdk1.7.0_04/jre/lib/amd64/libjavaplugin_jni.so ~/.mozilla/plugins/
ln -s /usr/java/jdk1.7.0_04/jre/lib/amd64/libnpjp2.so ~/.mozilla/plugins/

Just will mention that I don’t want to convince that OpenJDK is the blame in everything but the experiments were held on the freshly installed 12.04 and all the problems have been resolved after installing the proprietary version.

24
Sep

Parameterization of JUnit tests with the help of TwiP

Posted by eugene as Java

The TwiP (Test with Parameters) library allows us to parameterize. JUnit tests have rather more advantages than the built-in theories in JUnit:

  • allows to parameterize different tests and parameters by different sets of values
  • allows to define a method which will return one or massive of values by which the test should be parameterized

The example of using TwiP is represented below:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
import net.sf.twip.TwiP;
import net.sf.twip.Values;
 
import org.junit.Test;
import org.junit.runner.RunWith;
 
@RunWith(TwiP.class)
public class TestWithTwiP
{
    public static Integer[] oddNumbers = {1,3,5,7,9};
    public static Integer[] evenNumbers = {2,4,6,8,10};
 
    public static Integer[] methodNumbers()
    {
        List<Integer> numbers = new ArrayList<Integer>();
        numbers.addAll(Arrays.asList(oddNumbers));
        numbers.addAll(Arrays.asList(evenNumbers));
        return numbers.toArray(new Integer[10]);
    }
 
    public static List<Integer> methodNumbersList()
    {
        List<Integer> numbers = new ArrayList<Integer>();
        numbers.addAll(Arrays.asList(oddNumbers));
        numbers.addAll(Arrays.asList(evenNumbers));
        return numbers;
    }
 
    @Test
    public void testOddNumbers(@Values("oddNumbers") int oddNumber)
    {
        System.out.println("Odd number: " + oddNumber);
    }
 
    @Test
    public void testEvenNumbers(@Values("evenNumbers") int evenNumber)
    {
        System.out.println("Even number: " + evenNumber);
    }
 
    @Test
    public void testTwoArguments(@Values("oddNumbers") int oddNumber, @Values("evenNumbers") int evenNumber)
    {
        System.out.println("Odd number: " + oddNumber);
        System.out.println("Even number: " + evenNumber);
    }
 
    @Test
    public void testMethodArgument(@Values("methodNumbers") int number)
    {
        System.out.println("Number: " + number);
    }
 
    @Test
    public void testMethodArgumentReturnsList(@Values("methodNumbersList") int number)
    {
        System.out.println("Number: " + number);
    }
 
    @Test
    public void testCombinedMethodArgument(@Values("methodNumbers") int number, @Values("oddNumbers") int oddNumber)
    {
        System.out.println("Number: " + number);
        System.out.println("Odd number: " + oddNumber);
    }
}

All methods and variables which are the data sources must be be public and static (public static) and must return ony the referential types, primitives are not allowed.

In order to specify which data source will be used for the particular parameter the @Values annotation within which the name or class variable is used.

If you specify a few parameters test will be called for all possible combination of these parameters – their Cartesian product. If you want to call the test and all parameters to be moving simultaneously (i.e. from the first source – element 0, and from the second source – element 0 and so on), then it’s necessary to specify an extra class which will contain pairs of values (or more) and to pass it into the test.

20
Sep

Generating random numbers using Random.org

Posted by eugene as Java

Who tries to generate random numbers by using the arithmetic methods, that does certainly live in sin. – John von Neumann

There is such a good service random.org which has been repeatedly referred on Habr. The main object of the website is the generation of random numbers using the atmospheric noises. On the same website you can find the test results and comparison of radom and pseudo-random generators with the explanation what is better and why. This article describes a simple library for using website API.

Random.org

There are a lot of helpful functions that use generation of random numbers: coin toss, dice, cards shuffling, getting the lottery combinations, sound generation, bitmaps and so on. There is also the custom generation by the predefined distribution. In general, all this is not difficult, but the interesting fact is that the generation is performed with the using of atmospheric noises and it somehow magically allows you to get a better random than Random.nextInt(). Then I thought it would be nice to have in stock a library with such API and I’ve decided to write it.

Search

Before you write, you need to look for, perhaps someone already did that. Yes. Did.

  • Simple Random.Org Java Api – a simple lib with the method for generating integers but it pulls the Apache HTTP Client dependency, as much as kilobytes.
  • Java TRNG client – here all is more serious. 40 kilobytes and generation of numbers by means of two(!) websites. Yes, the lack is that the lib has been created for cryptography and hence the handling is performed by bits, bytes and all is complicated at all.

Basically, I’ve decided to write my own.

API

Random.org represents the primitive HTTP GET API but nothing else is needed. Totally there are 4 types of operations.

Integer Generator

Generates random integer numbers in the predefined range. For example, here is request for tossing two dices looks like:

http://www.random.org/integers/?num=2&min=1&max=6&col=1&base=10&format=plain&rnd=new

Sequence Generator

Generates a sequence with all the unique integer numbers in the predefined range. Basically, what does Collections.shuffle(). For example, here is how the request for shuffling the cards looks like:

http://www.random.org/sequences/?min=1&max=52&col=1&format=plain&rnd=new

String Generator

Generates a random string of the predefined size with the opportunity to choose the set of symbols (numbers, lower case, upper case). Here is how you can generate a nickname to your person password:

http://www.random.org/strings/?num=1&len=12&digits=on&upperalpha=on&loweralpha=on&unique=on&format=plain&rnd=new

Quota Checker

Well, as you know this is not free. Although they provide millions of free bits per day. This is actually more than enough. And you can find out how much is left by going over the following link:

http://www.random.org/quota/?format=plain
If you clicked three previous links, you’ve already spent ~1500 bits.

Errors

In case of success, the server returns code 200, fail – code 503. These are all the errors.

There was written the library of five classes for this API in Java where the call of all the above methods is represented in a simple and comprehensive way.

// dice
IntegerGenerator ig = new IntegerGenerator();
ig.generate(1, 6, 2);
// cards shuffling
SequenceGenerator sg = new SequenceGenerator();
sg.generate(1, 52);
// new password
StringGenerator strg = new StringGenerator();
strg.generate(12, 1, true, true, true, true);
// how much bits left
QuotaChecker qc = new QuotaChecker();
qc.quota();

And perhaps that is all. On github you can find the sources and download the lib with the original randomorg name (6 kilobytes).

18
Sep

The Java .class file or for which Java the class is compiled

Posted by eugene as Java

It’s often necessary to find out the version of the binary .class file. For example, the web/application server is working under the fifth Java and locally we have the sixth one. Hence, in this way the problem is difficult to determine.

Having the .class file and staff jdk means, you can quickly and qualitively get information about the compiled class. In the jdk/bin folder you can find an excellent tool javap.

With its help, when you insert the following line in the command line:

javap -verbose MyClass

You will get the result:

Compiled from "MyClass.java"
public class MyClass extends java.lang.Object
SourceFile: "MyClass.java"
minor version: 0
major version: 50
Constant pool:
const #1 = class #2; // MyClass
const #2 = Asciz MyClass;
const #3 = class #4; // java/lang/Object
const #4 = Asciz java/lang/Object;

We need the following line:

major version : 50

To define the version of the class that has been compiled, you can use the table below:

major minor Java platform version
45 3 1.0
45 3 1.1
46 0 1.2
47 0 1.3
48 0 1.4
49 0 1.5
50 0 1.6
17
Jul

Removal of various diacritical characters from a string

Posted by eugene as Java

Got a problem – how to replace characters of national encoding in a string with the corresponding Latin ones.

For example, how to get explication from the explicación string.

package com.blogspot.atamanenko;
 
import java.text.Normalizer;
import java.text.Normalizer.Form;
 
public class StringNormalizer {
 
    public static String normalize(String string) {
        return Normalizer.normalize(string, Form.NFD)
            .replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
    }
}

Calling of Normalizer.normalize get the normalization of the input string. The subsequent call of the regular expression removes all the diacritical symbols received after the normalization.

17
Jul

A bit about the virtual methods in Java

Posted by eugene as Java

Today I want to look through the following features of re-defining of methods in Java. You cannot re-define the following in Java:

  • class fields
  • constructors, class initializers
  • Static methods
  • Static fields

You can read about it in Java Language Specification, §8.4.8 in more details.

So, all the non-static non-private (i.e. protected, package and public) methods are virtual. The ‘final’ keyword bans the possibility of the further re-defining of the method in the sub-classes. Let’s review the following example:

public class A {
     int i = 3;
     int getI() {return i;}
}
 
public class B extends A{
     int i = 5;
     int getI() {return i;}
}
 
A a = new B();
System.out.println(a.i);
System.out.println(a.getI());

Question: what will this code return?

Answer:

1. As the class fields are not inherited, then class A has its own i field and class B has the i field. As polymorphism is not actual for the fields, then when getting to a.i we are getting to the A class, that’s why 3 will be shown on the screen.

When calling the a.get() method, polymorphism should be used here, that’s why the method will be called from the class which instance has been created. Consequently, we’ll receive 5.

Another example:

public class A {
     static int i = 3;
     static int getI() {return i;}
}
 
public class B extends A{
     static int i = 5;
     static int getI() {return i;}
}
 
A a = new B();
System.out.println(a.i);
System.out.println(a.getI());

Static fields and methods are not virtual, that’s why both calls will return us 3.

11
Jul

Implementation of concurrent HashSet in Java

Posted by eugene as Java

Undortunately there’s no full implementation of a concurrent HashSet as in case with HashMap – java.util.concurrent.ConcurrentHashMap. There’s CopyOnWriteArraySet which uses CopyOnWriteArrayList inside of it but it has some disadvantages:

  • Searching of elements will be slower as it’s implemented by equals in Lists and not by hashcode -> equals.
  • Inability to remove objects while iterating (iterator.remove () – not implemented) and it is clear why not as the collection copy is used while the iteration.

But out there ConcurrentHashSet can be done on the basis of ConcurrentHashMap writing down an element as the key and any dummy-object into the value. Such implementation is represented in the form of org.jboss.util.collection.ConcurrentSet from the jboss-common-core library.

05
Jul

Collecting the statistics of using the classes with the help of Cobertura

Posted by eugene as Java

On the current project I’ve got a necessity to get the list of the unused classes with the aim to avoid out of them:)

As there are lots of classes and the connections between them cannot be always followed in IDE now here is the situation when a rare project can live without Spring, but as for me, I’m lucky for another time. We use the self-written decision which used to work out a bit and to learn doing dependency-injection in order to unleash the classes between each other and to start getting avoid of singletons which only spoil the life.

In order to assess tbe code coverage by tests we use Cobertura. That’s definitely why I decided to use exactly it for collecting the statistics of classes usage – I had to barely add the instrumently assembled jar-file which should also get into the final build.

Actually the collecting of statistics itself is concluded in that the instrumented classes should be used by the application at runtime. Everything is exactly as in the coverage assessment with the only exception that we do not run the tests but the really working application one of the test stands.

Below is represented the example of Ant-script which instruments the classes:

<?xml version="1.0" encoding="UTF-8"?>
<project name="UsageStatistics" basedir=".">
<property name="src.main.java" location="${basedir}/src/main/java" />
<property name="src.test.java" location="${basedir}/src/test/java" />
<property name="lib" location="${basedir}/lib" />
<property name="target" location="${basedir}/target" />
<property name="target.compile" location="${target}/compile" />
<property name="target.compile.classes" location="${target.compile}/classes" />
<property name="target.instrument" location="${target}/instrument" />
<property name="target.instrument.classes" location="${target.instrument}/classes" />
<property name="target.instrument.report" location="${target.instrument}/report" />
<property name="target.test" location="${target}/test" />
<property name="target.test.classes" location="${target.test}/classes" />
<property name="target.test.report" location="${target.test}/report" />
<property name="target.package" location="${target}/package" />
<target name="compile">
<mkdir dir="${target.compile.classes}" />
<javac srcdir="${src.main.java}" destdir="${target.compile.classes}" source="1.5" debug="on" debuglevel="lines,source">
<classpath>
<fileset dir="${lib}" includes="**/*.jar" />
</classpath>
</javac>
</target>
<target name="instrument" depends="compile">
<mkdir dir="${target.instrument.classes}" />
<copy todir="${target.instrument.classes}">
<fileset dir="${target.compile.classes}" includes="**/*"/>
</copy>
<cobertura-instrument todir="${target.instrument.classes}" datafile="${target.instrument}/cobertura.ser">
<fileset dir="${target.instrument.classes}" includes="**/*.class"/>         </cobertura-instrument>
<copy file="${target.cobertura}/cobertura.ser" tofile="${target.cobertura}/cobertura-clean.ser"/>     </target>
<target name="test-compile" depends="instrument">
<mkdir dir="${target.test.classes}" />
<javac srcdir="${src.test.java}" destdir="${target.test.classes}" source="1.5" debug="on" debuglevel="lines,source">
<classpath>
<fileset dir="${target.instrument.classes}" includes="**/*" />
<fileset dir="${lib}" includes="**/*.jar" />
</classpath>
</javac>
</target>
<target name="test" description="Run tests" depends="compile-test" unless="test.skip">
<mkdir dir="${target.test}" />
<mkdir dir="${target.test.report}" />
<junit printsummary="true" fork="yes" forkmode="once">
<classpath>                 
<pathelement location="${target.instrument.classes}"/>
<pathelement location="${target.test.classes}"/>
<fileset dir="${lib}" includes="**/*.jar" />
</classpath>
<sysproperty key="net.sourceforge.cobertura.datafile" file="${target.instrument}/cobertura.ser" />
<batchtest todir="${target.test.report}">
<fileset dir="${target.compile.test}">
<include name="**/*Test.class"/>
</fileset>                 
<formatter type="xml"/>
</batchtest>
</junit>
<cobertura-report datafile="${target.instrument}/cobertura.ser" format="html" destdir="${target.instrument.report}" srcdir="${src.main.java}" />
</target>
<target name="package" depends="test">
<mkdir dir="${target.package}" />
<jar jarfile="${target.package}/package.jar" basedir="${target.compile.classes}"/>
<jar jarfile="${target.package}/package-instrumented.jar" basedir="${target.instrument.classes}"/>
</target>
</project>

A very important note: during the instrumentation Cobertura generates the file where recorded the information about all the existing classes, and it should be used at the time of collecting the statistics. Otherwise Cobertura will create a new file where the information will be only about those classes which have been used by the application and there will be no use of it. That’s why do not forget to copy this file to the server that will run your application.

In order to make Cobertura find the file on the server, the file location should be transmitted to the application in any way. There are some ways to do so:

- put the cobertura.properties file in the classpath of the application and to write there net.sourceforge.cobertura.datafile=/path/to/file

- transmit the JVM parameter -Dnet.sourceforge.cobertura.datafile=/path/to/file

If your application consists of several Java processes they can be safely use the same file for collecting the statistics.

The screenshots of the reports of statistics and coverage are represented below for comparison. Now the difference is not so much as part of packages I’ve already removed:)

Statistics of classes usage report

Statistics of classes usage report

Code coverage by tests

Code coverage by tests

When comparing the reports you can notice that package23 is being used although it’s not covered by tests.

package22 is not being used but it’s covered by tests at the same time, the package16, package24, package25 are not being used

26
Jun

Testing of Java Mail API

Posted by eugene as Java

I want to tell you about one simple method in this article on how to test code which uses Java Mail API.

The difficulties in testing such code are as follows:

  • message sending is implemented with the help of the static javax.mail.Transport.send method and it’s difficult to kill it
  • the mail server, through which the messages will be sent, is required for testing
  • it is required to fill out the client in order to compare what has been sent with what has been received
  • if several developers simulteneously launch tests then the duplicates will get to the server; to avoid the conflicts, it is necessary to complicate the tests, so that some unique identifier will be generated with the help of which you can search messages

You can definitely kill javax.mail.Transport.send. There are exist lots of mock-frameworks which allow to do this but there is the better and easier way!

The thing is that the Java Mail API developers made it possible to expand its service providers in the META-INF/javamail.providers file. I won’t get into the technical details because I do not know them:)

Fortunately there are people in the world who have already thought about it and wrote such mock-provider: http://java.net/projects/mock-javamail. To use it, it’s enough to add mock-javamail.jar to the classpath and that’s all.

This provider acts as the in-memory mail server. This means that all sent messages are stored in the mailbox from which they can be extracted. Each mailbox is associated with every unique email address that is created automatically when you send a message.

The acces to the mailbox is granted via the Mailbox class. This class is responsible for the storing of received messages the usual collection and allows you to add/remove messages. In addition, this class has two static factory methods which return the mailbox object passed to the mail addresss (if there is no mailbox, it will be created). Here’s an example of the call:

Mailbox mailbox = Mailbox.get("some@email.com");

Another static method which in my point of view deserves attention is Mailbox.clearAll(). This method removes all the mailboxes. It is useful to call it before the beginning of the test so that the data will not interfere with the data from the previous ones. The example of use:

Mailbox.clearAll();

Below I’ll give an example of using this provider:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.nikisoft.articale</groupId>
<artifactId>mock-javamail</artifactId>
<version>1.0.0</version>     
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.jvnet.mock-javamail</groupId>
<artifactId>mock-javamail</artifactId>
<version>1.11</version>
</dependency>
</dependencies> </project>
package ru.nikisoft.article.mockjavamail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import org.junit.Test;
import org.jvnet.mock_javamail.Mailbox;
public class MailSenderTest {
@Test
public void testSend() throws MessagingException, IOException     {
Mailbox.clearAll();
Mailbox mailbox = Mailbox.get("to@email.com");
MailSender mailSender = new MailSender("smtp.host", "from@email.com");
mailSender.send("to@email.com", "Subject: testSend", "Body: testSend");
assertEquals(1, mailbox.getNewMessageCount());
assertFromEquals(mailbox.get(0), "from@email.com");
assertToEquals(mailbox.get(0), "to@email.com");
assertSubjectEquals(mailbox.get(0), "Subject: testSend");
assertBodyEquals(mailbox.get(0), "Body: testSend");     }
private void assertFromEquals(Message message, String... expectedFrom) throws MessagingException     {
Set<String> expectedFromSet = new HashSet<String>(Arrays.asList(expectedFrom));
           for (Address actualFrom: message.getFrom())
		   {
		   expectedFromSet.remove(actualFrom.toString());
		   }
		   if (expectedFromSet.size() > 0)
		   fail("From should contain these addresses: " + expectedFromSet);     }
		   private void assertToEquals(Message message, String... expectedTo) throws MessagingException     {
		   Set<String> expectedToSet = new HashSet<String>
		   (Arrays.asList(expectedTo));
		   for (Address actualFrom: message.getRecipients(RecipientType.TO))
		   {
		   expectedToSet.remove(actualFrom.toString());
		   }
		   if (expectedToSet.size() > 0)
		   fail("From should contain these addresses: " + expectedToSet);
		   }
		   private void assertSubjectEquals(Message message, String expectedSubject) throws MessagingException
		   {
		   String actualSubject = message.getSubject();
		   assertEquals(expectedSubject, actualSubject);
		   }
		   private void assertBodyEquals(Message message, String expectedBody) throws IOException, MessagingException
		   {
		   String contentType = message.getContentType();
		   if (contentType.contains("text/plain"))
		   {
		   String actualBody = (String) message.getContent();
		   assertEquals(expectedBody, actualBody);
		   return;
		   }
		   fail("Unsupported content-type: " + contentType);
		   }
		   }
package ru.nikisoft.article.mockjavamail;
import java.util.Properties;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class MailSender {
private Properties properties;
public MailSender(String host, String from)
{
properties = new Properties();
properties.put("mail.transport.protocol", "smtp");
properties.put("mail.smtp.host", host);
properties.put("mail.from", from);
}
public void send(String to, String subject, String body) throws MessagingException
{
Session session = Session.getDefaultInstance(properties);
MimeMessage message = new MimeMessage(session);
message.setFrom(InternetAddress.getLocalAddress(session));
message.setRecipients(RecipientType.TO, to);
message.setSubject(subject);
message.setText(body);
Transport.send(message);
}
}