diff --git a/README.md b/README.md
index 320845d..0aba3d7 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,24 @@
-quality-day-training-tasks
-==========================
+#Excersie 2: Asynchronous method call
+##Introduction
+This lesson is about following skills:
+* creating asynchronous methods in enterprise beans
+* EJB self invocation
+* concurrency
-Various tasks and problems to solve
+Expected result of this exercise is an EJB application which uses self invoked asynchronous method calculatePi.
+
+##Before you start, read about...
+* Asynchronous invocation: [http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html]
+* Session Context [http://docs.oracle.com/javaee/6/api/javax/ejb/SessionContext.html#getBusinessObject(java.lang.Class)]
+
+##The exercise
+To complete this exercise you need to follow these steps:
+* Refactor calculatePi in `PiCalculator.java` to return promise (read Asynchronous invocation) instead of Object
+* Make calculatePi asynchronous
+* Annotate Session Context to be injected properly
+* In piFullCalculator use sessionContext to recover business object of class `PiCalculator.java` and assign it to the variable
+* Use business object for self invocation of asynchronous method calculatePi and pass
+iterations as parameter (Important note: You can't invoke private functions)
+* Assign return value to existing variable piFuture
+
+Good luck !
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..bd6ce55
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,95 @@
+
+
+ 4.0.0
+ pl.itcrowd.java.exercises
+ java-exercises
+ war
+ 1.0.0-SNAPSHOT
+
+
+
+ org.jboss.as.plugins
+ jboss-as-maven-plugin
+ ${version.jbossas}
+
+ ${project.artifactId}
+ true
+ ${project.groupId}
+ true
+
+
+
+ maven-war-plugin
+
+ false
+
+
+
+
+
+
+ org.jboss.spec.javax.ejb
+ jboss-ejb-api_3.1_spec
+ 1.0.1.Final
+ provided
+
+
+ javax.annotation
+ jsr250-api
+ 1.0
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.7
+
+
+ org.slf4j
+ slf4j-simple
+ 1.7.7
+
+
+ junit
+ junit
+ 4.8.1
+ test
+
+
+ org.jboss.arquillian.junit
+ arquillian-junit-container
+ test
+
+
+ org.jboss.as
+ jboss-as-arquillian-container-remote
+ 7.1.1.Final
+ test
+
+
+
+
+
+ org.jboss.shrinkwrap.resolver
+ shrinkwrap-resolver-bom
+ 2.2.0-beta-1
+ import
+ pom
+
+
+ org.jboss.arquillian
+ arquillian-bom
+ 1.1.5.Final
+ import
+ pom
+
+
+
+
+ 1.7
+ UTF-8
+ UTF-8
+ UTF-8
+ 7.1.1.Final
+
+
diff --git a/src/main/java/Main.java b/src/main/java/Main.java
new file mode 100644
index 0000000..e1b035d
--- /dev/null
+++ b/src/main/java/Main.java
@@ -0,0 +1,36 @@
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.PostConstruct;
+import javax.ejb.EJB;
+import javax.ejb.Singleton;
+import javax.ejb.Startup;
+
+@Startup
+@Singleton
+public class Main {
+
+ private Logger logger = LoggerFactory.getLogger(Main.class);
+
+ private Double adminPiResult;
+
+ @EJB
+ private PiCalculator calculator;
+
+ @PostConstruct
+ public void main() throws Exception
+ {
+ setAdminPiResult(calculator.piFullCalculator(10000000));
+ logger.info("admin pi precision: " + Double.toString(getAdminPiResult()));
+ }
+
+ public Double getAdminPiResult()
+ {
+ return adminPiResult;
+ }
+
+ public void setAdminPiResult(Double adminPiResult)
+ {
+ this.adminPiResult = adminPiResult;
+ }
+}
diff --git a/src/main/java/PiCalculator.java b/src/main/java/PiCalculator.java
new file mode 100644
index 0000000..07ef071
--- /dev/null
+++ b/src/main/java/PiCalculator.java
@@ -0,0 +1,48 @@
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ejb.SessionContext;
+import javax.ejb.Stateless;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+@Stateless
+public class PiCalculator {
+
+ private Logger logger = LoggerFactory.getLogger(PiCalculator.class);
+
+ private SessionContext sessionContext;
+
+ public Double piFullCalculator(int iterations) throws ExecutionException, InterruptedException
+ {
+ Long threadId = Thread.currentThread().getId();
+
+ //You are supposed to instantiate piFuture with promise from calculatePi function(you need to fix calculatePi return value)
+ final Future piFuture = null;
+ logger.info("piFullCalculator should appear before calculatePi: " + Long.toString(threadId));
+
+ final Object monitor = new Object();
+ while(!piFuture.isDone()) {
+ logger.info("Waiting...");
+ //noinspection SynchronizationOnLocalVariableOrMethodParameter
+ synchronized (monitor) {
+ monitor.wait(1000);
+ }
+ }
+
+ return piFuture.get();
+ }
+
+ private Object calculatePi(int iterations)
+ {
+ double pi = 4;
+ boolean plus = false;
+ for (int i = 3; i < iterations; i += 2) {
+ pi = plus ? (pi + 4.0 / i) : (pi - 4.0 / i);
+ plus = !plus;
+ }
+ Long threadId = Thread.currentThread().getId();
+ logger.info("calculatePi, thread id: " + Long.toString(threadId));
+ return pi;
+ }
+}
diff --git a/src/main/webapp/WEB-INF/jboss-ejb3.xml b/src/main/webapp/WEB-INF/jboss-ejb3.xml
new file mode 100644
index 0000000..1a3d44e
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jboss-ejb3.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ exercise
+ *
+
+
+
+
diff --git a/src/test/java/MainTest.java b/src/test/java/MainTest.java
new file mode 100644
index 0000000..2dc1558
--- /dev/null
+++ b/src/test/java/MainTest.java
@@ -0,0 +1,33 @@
+import junit.framework.Assert;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.EJB;
+import java.io.File;
+
+@RunWith(Arquillian.class)
+public class MainTest {
+
+ @EJB
+ private Main main;
+
+ @Deployment
+ public static WebArchive createDeployment()
+ {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(Main.class, PiCalculator.class)
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF/jboss-ejb3.xml"))
+ .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
+ }
+
+ @Test
+ public void should_calculatePi_equal() throws Exception
+ {
+ Assert.assertEquals(main.getAdminPiResult(), 3.1415924535897797d);
+ }
+}
diff --git a/src/test/java/PiCalculatorTest.java b/src/test/java/PiCalculatorTest.java
new file mode 100644
index 0000000..f1ee67b
--- /dev/null
+++ b/src/test/java/PiCalculatorTest.java
@@ -0,0 +1,34 @@
+import junit.framework.Assert;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.EJB;
+import java.io.File;
+import java.util.concurrent.Future;
+
+@RunWith(Arquillian.class)
+public class PiCalculatorTest {
+
+ @EJB
+ private PiCalculator piCalculator;
+
+ @Deployment
+ public static WebArchive createDeployment()
+ {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(PiCalculator.class)
+ .addAsWebInfResource(new File("src/main/webapp/WEB-INF/jboss-ejb3.xml"))
+ .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
+ }
+
+ @Test
+ public void should_calculatePi_be_called_asynchronously() throws Exception
+ {
+ Assert.assertEquals(((Future) piCalculator.calculatePi(10000)).isDone(), false);
+ }
+}