diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java
index b275688d2c56318b8750c52b9ee966373ea84caa..569b5203b5c895e6c702476d71108580e134aeab 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java
@@ -128,7 +128,12 @@ public class OlmAccountTest {
      */
     @Test
     public void test05IdentityKeys() {
-        Map<String, String> identityKeys = mOlmAccount.identityKeys();
+        Map<String, String> identityKeys = null;
+        try {
+            identityKeys = mOlmAccount.identityKeys();
+        } catch (Exception e) {
+            assertTrue("identityKeys failed " + e.getMessage(), false);
+        }
         assertNotNull(identityKeys);
         Log.d(LOG_TAG,"## testIdentityKeys Keys="+identityKeys);
 
@@ -157,8 +162,15 @@ public class OlmAccountTest {
      */
     @Test
     public void test07GenerateOneTimeKeys() {
-        int retValue = mOlmAccount.generateOneTimeKeys(GENERATION_ONE_TIME_KEYS_NUMBER);
-        assertTrue(0==retValue);
+        String error = null;
+
+        try {
+            mOlmAccount.generateOneTimeKeys(GENERATION_ONE_TIME_KEYS_NUMBER);
+        } catch (Exception e) {
+            error = e.getMessage();
+        }
+
+        assertTrue(null == error);
     }
 
     /**
@@ -167,7 +179,13 @@ public class OlmAccountTest {
     @Test
     public void test08OneTimeKeysJsonFormat() {
         int oneTimeKeysCount = 0;
-        Map<String, Map<String, String>> oneTimeKeysJson = mOlmAccount.oneTimeKeys();
+        Map<String, Map<String, String>> oneTimeKeysJson = null;
+
+        try {
+            oneTimeKeysJson = mOlmAccount.oneTimeKeys();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
         assertNotNull(oneTimeKeysJson);
 
         try {
@@ -195,26 +213,40 @@ public class OlmAccountTest {
         long sessionId = olmSession.getOlmSessionId();
         assertTrue(0 != sessionId);
 
-        int sessionRetCode = mOlmAccount.removeOneTimeKeysForSession(olmSession);
-        // test against no matching keys
-        assertTrue(1 == sessionRetCode);
+        String errorMessage = null;
+
+        try {
+            mOlmAccount.removeOneTimeKeys(olmSession);
+        } catch (Exception e) {
+            errorMessage = e.getMessage();
+        }
+        assertTrue(null != errorMessage);
 
         olmSession.releaseSession();
         sessionId = olmSession.getOlmSessionId();
-        assertTrue("sessionRetCode="+sessionRetCode,0 == sessionId);
+        assertTrue(0 == sessionId);
     }
 
     @Test
     public void test11MarkOneTimeKeysAsPublished() {
-        int retCode = mOlmAccount.markOneTimeKeysAsPublished();
-        // if OK => retCode=0
-        assertTrue(0 == retCode);
+        try {
+            mOlmAccount.markOneTimeKeysAsPublished();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
     }
 
     @Test
     public void test12SignMessage() {
         String clearMsg = "String to be signed by olm";
-        String signedMsg  = mOlmAccount.signMessage(clearMsg);
+        String signedMsg  = null;
+
+        try {
+            signedMsg = mOlmAccount.signMessage(clearMsg);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         assertNotNull(signedMsg);
         // additional tests are performed in test01VerifyEd25519Signing()
     }
@@ -237,12 +269,29 @@ public class OlmAccountTest {
             assertTrue(e.getMessage(),false);
         }
 
-        int retValue = accountRef.generateOneTimeKeys(GENERATION_ONE_TIME_KEYS_NUMBER);
-        assertTrue(0==retValue);
+        try {
+            accountRef.generateOneTimeKeys(GENERATION_ONE_TIME_KEYS_NUMBER);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(),false);
+        }
 
         // get keys references
-        Map<String, String> identityKeysRef = accountRef.identityKeys();
-        Map<String, Map<String, String>> oneTimeKeysRef = accountRef.oneTimeKeys();
+        Map<String, String> identityKeysRef = null;
+
+        try {
+            identityKeysRef = accountRef.identityKeys();
+        } catch (Exception e) {
+            assertTrue("identityKeys failed " + e.getMessage(), false);
+        }
+
+        Map<String, Map<String, String>> oneTimeKeysRef = null;
+
+        try {
+            oneTimeKeysRef = accountRef.oneTimeKeys();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         assertNotNull(identityKeysRef);
         assertNotNull(oneTimeKeysRef);
 
@@ -304,12 +353,25 @@ public class OlmAccountTest {
     @Test
     public void test14GenerateOneTimeKeysError() {
         // keys number = 0 => no error
-        int retValue = mOlmAccount.generateOneTimeKeys(0);
-        assertTrue(0==retValue);
+
+        String errorMessage = null;
+        try {
+            mOlmAccount.generateOneTimeKeys(0);
+        } catch (Exception e) {
+            errorMessage = e.getMessage();
+        }
+
+        assertTrue(null == errorMessage);
 
         // keys number = negative value
-        retValue = mOlmAccount.generateOneTimeKeys(-50);
-        assertTrue(-1==retValue);
+        errorMessage = null;
+        try {
+            mOlmAccount.generateOneTimeKeys(-50);
+        } catch (Exception e) {
+            errorMessage = e.getMessage();
+        }
+
+        assertTrue(null != errorMessage);
     }
 
     @Test
@@ -321,9 +383,16 @@ public class OlmAccountTest {
             assertTrue(e.getMessage(),false);
         }
 
-        int sessionRetCode = olmAccount.removeOneTimeKeysForSession(null);
+        boolean sessionRetCode = true;
+
+        try {
+            sessionRetCode = olmAccount.removeOneTimeKeys(null);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         // test against no matching keys
-        assertTrue(-1 == sessionRetCode);
+        assertFalse(sessionRetCode);
 
         olmAccount.releaseAccount();
     }
@@ -336,7 +405,13 @@ public class OlmAccountTest {
         } catch (OlmException e) {
             assertTrue(e.getMessage(),false);
         }
-        String signedMsg  = olmAccount.signMessage(null);
+        String signedMsg = null;
+
+        try {
+            signedMsg = olmAccount.signMessage(null);
+        } catch (Exception e) {
+        }
+
         assertNull(signedMsg);
 
         olmAccount.releaseAccount();
diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java
index 675d72cbaf702877e876e4f83155a7a12ec22eb9..e8b2288fb6c4c485d55525981360a9a497dbeb55 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java
@@ -92,13 +92,32 @@ public class OlmSessionTest {
         assertTrue(0!=aliceAccount.getOlmAccountId());
 
         // get bob identity key
-        Map<String, String> bobIdentityKeys = bobAccount.identityKeys();
+        Map<String, String> bobIdentityKeys = null;
+
+        try {
+            bobIdentityKeys = bobAccount.identityKeys();
+        } catch (Exception e) {
+            assertTrue("identityKeys failed " + e.getMessage(), false);
+        }
+
         bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
         assertTrue(null!=bobIdentityKey);
 
         // get bob one time keys
-        assertTrue(0==bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER));
-        Map<String, Map<String, String>> bobOneTimeKeys = bobAccount.oneTimeKeys();
+        try {
+            bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
+        Map<String, Map<String, String>> bobOneTimeKeys = null;
+
+        try {
+            bobOneTimeKeys = bobAccount.oneTimeKeys();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1);
         assertNotNull(bobOneTimeKey);
 
@@ -141,7 +160,13 @@ public class OlmSessionTest {
         assertTrue(clearMsg.equals(decryptedMsg));
 
         // clean objects..
-        assertTrue(0==bobAccount.removeOneTimeKeysForSession(bobSession));
+        boolean res = false;
+        try {
+            res = bobAccount.removeOneTimeKeys(bobSession);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+        assertTrue(res);
 
         // release accounts
         bobAccount.releaseAccount();
@@ -191,13 +216,32 @@ public class OlmSessionTest {
         assertTrue(0!=aliceAccount.getOlmAccountId());
 
         // get bob identity key
-        Map<String, String> bobIdentityKeys = bobAccount.identityKeys();
+        Map<String, String> bobIdentityKeys = null;
+
+        try {
+            bobIdentityKeys = bobAccount.identityKeys();
+        } catch (Exception e) {
+            assertTrue("identityKeys failed " + e.getMessage(), false);
+        }
+
         bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
         assertTrue(null!=bobIdentityKey);
 
         // get bob one time keys
-        assertTrue(0==bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER));
-        Map<String, Map<String, String>> bobOneTimeKeys = bobAccount.oneTimeKeys();
+        try {
+            bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
+        Map<String, Map<String, String>> bobOneTimeKeys = null;
+
+        try {
+            bobOneTimeKeys = bobAccount.oneTimeKeys();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1);
         assertNotNull(bobOneTimeKey);
 
@@ -279,7 +323,14 @@ public class OlmSessionTest {
         assertTrue(clearMsg1.equals(decryptedMsg1));
 
         // clean objects..
-        assertTrue(0==bobAccount.removeOneTimeKeysForSession(bobSession));
+        boolean res = false;
+        try {
+            res = bobAccount.removeOneTimeKeys(bobSession);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+        assertTrue(res);
+
         bobAccount.releaseAccount();
         aliceAccount.releaseAccount();
         assertTrue(bobAccount.isReleased());
@@ -369,15 +420,46 @@ public class OlmSessionTest {
         }
 
         // get bob/luke identity key
-        Map<String, String> bobIdentityKeys = bobAccount.identityKeys();
-        Map<String, String> aliceIdentityKeys = aliceAccount.identityKeys();
+        Map<String, String> bobIdentityKeys = null;
+
+        try {
+            bobIdentityKeys = bobAccount.identityKeys();
+        } catch (Exception e) {
+            assertTrue("identityKeys failed " + e.getMessage(), false);
+        }
+
+        Map<String, String> aliceIdentityKeys = null;
+
+        try {
+            aliceIdentityKeys = aliceAccount.identityKeys();
+        } catch (Exception e) {
+            assertTrue("identityKeys failed " + e.getMessage(), false);
+        }
+
         String bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
         String aliceIdentityKey = TestHelper.getIdentityKey(aliceIdentityKeys);
 
         // get bob/luke one time keys
-        assertTrue(0 == bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER));
-        assertTrue(0 == aliceAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER));
-        Map<String, Map<String, String>> bobOneTimeKeys = bobAccount.oneTimeKeys();
+        try {
+            bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
+        try {
+            aliceAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
+        Map<String, Map<String, String>> bobOneTimeKeys = null;
+
+        try {
+            bobOneTimeKeys = bobAccount.oneTimeKeys();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         String bobOneTimeKey1 = TestHelper.getOneTimeKey(bobOneTimeKeys, 1);
 
         // create alice inbound session for bob
@@ -401,7 +483,14 @@ public class OlmSessionTest {
         //assertTrue(false==bobSession.matchesInboundSessionFrom(bobIdentityKey, encryptedAliceToBobMsg1.mCipherText));
 
         // release objects
-        assertTrue(0==bobAccount.removeOneTimeKeysForSession(bobSession));
+        boolean res = false;
+        try {
+            res = bobAccount.removeOneTimeKeys(bobSession);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+        assertTrue(res);
+
         aliceAccount.releaseAccount();
         bobAccount.releaseAccount();
         assertTrue(aliceAccount.isReleased());
@@ -443,13 +532,32 @@ public class OlmSessionTest {
         assertTrue(0!=aliceAccount.getOlmAccountId());
 
         // get bob identity key
-        Map<String, String> bobIdentityKeys = bobAccount.identityKeys();
+        Map<String, String> bobIdentityKeys = null;
+
+        try {
+            bobIdentityKeys = bobAccount.identityKeys();
+        } catch (Exception e) {
+            assertTrue("identityKeys failed " + e.getMessage(), false);
+        }
+
         bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
         assertTrue(null!=bobIdentityKey);
 
         // get bob one time keys
-        assertTrue(0==bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER));
-        Map<String, Map<String, String>> bobOneTimeKeys = bobAccount.oneTimeKeys();
+        try {
+            bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
+        Map<String, Map<String, String>> bobOneTimeKeys = null;
+
+        try {
+            bobOneTimeKeys = bobAccount.oneTimeKeys();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1);
         assertNotNull(bobOneTimeKey);
 
@@ -538,7 +646,14 @@ public class OlmSessionTest {
             assertTrue(clearMsg3.equals(decryptedMsg3));
 
             // clean objects..
-            assertTrue(0==bobAccount.removeOneTimeKeysForSession(bobSession));
+            boolean res = false;
+            try {
+                res = bobAccount.removeOneTimeKeys(bobSession);
+            } catch (Exception e) {
+                assertTrue(e.getMessage(), false);
+            }
+            assertTrue(res);
+
             bobAccount.releaseAccount();
             aliceAccount.releaseAccount();
             assertTrue(bobAccount.isReleased());
@@ -588,13 +703,32 @@ public class OlmSessionTest {
         }
 
         // get bob identity key
-        Map<String, String> bobIdentityKeys = bobAccount.identityKeys();
+        Map<String, String> bobIdentityKeys = null;
+
+        try {
+            bobIdentityKeys = bobAccount.identityKeys();
+        } catch (Exception e) {
+            assertTrue("identityKeys failed " + e.getMessage(), false);
+        }
+
         String bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
         assertTrue(null != bobIdentityKey);
 
         // get bob one time keys
-        assertTrue(0 == bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER));
-        Map<String, Map<String, String>> bobOneTimeKeys = bobAccount.oneTimeKeys();
+        try {
+            bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
+        Map<String, Map<String, String>> bobOneTimeKeys = null;
+
+        try {
+            bobOneTimeKeys = bobAccount.oneTimeKeys();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         assertNotNull(bobOneTimeKeys);
         String bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1);
         assertNotNull(bobOneTimeKey);
@@ -678,7 +812,14 @@ public class OlmSessionTest {
         assertTrue(!aliceSession.matchesInboundSessionFrom(null,null));
 
         // release objects
-        assertTrue(0==bobAccount.removeOneTimeKeysForSession(bobSession));
+        boolean res = false;
+        try {
+            res = bobAccount.removeOneTimeKeys(bobSession);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+        assertTrue(res);
+
         aliceAccount.releaseAccount();
         bobAccount.releaseAccount();
         assertTrue(aliceAccount.isReleased());
diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java
index e3ca544a7e4744412fef312fd8d4fd5cc3edd2c7..4096001e990ab45edd0d86340ff22389789b6b89 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java
@@ -71,11 +71,25 @@ public class OlmUtilityTest {
         assertNotNull(account);
 
         // sign message
-        String messageSignature = account.signMessage(message);
+        String messageSignature = null;
+
+        try {
+            messageSignature = account.signMessage(message);
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         assertNotNull(messageSignature);
 
         // get identities key (finger print key)
-        Map<String, String> identityKeys = account.identityKeys();
+        Map<String, String> identityKeys = null;
+
+        try {
+            identityKeys = account.identityKeys();
+        } catch (Exception e) {
+            assertTrue("identityKeys failed " + e.getMessage(), false);
+        }
+
         assertNotNull(identityKeys);
         fingerPrintKey = TestHelper.getFingerprintKey(identityKeys);
         assertTrue("fingerprint key missing",!TextUtils.isEmpty(fingerPrintKey));
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
index 649085e439b6378dfd5aa13632429aebe5dded48..3107ff3fbfb7fdc185c060c1bf308216f24ef07f 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
@@ -63,9 +63,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
     private transient long mNativeId;
 
     public OlmAccount() throws OlmException {
-        if(!initNewAccount()) {
-            throw new OlmException(OlmException.EXCEPTION_CODE_INIT_ACCOUNT_CREATION,OlmException.EXCEPTION_MSG_INIT_ACCOUNT_CREATION);
-        }
+        initNewAccount();
     }
 
     /**
@@ -97,11 +95,14 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
      * Create and initialize a native account instance.<br>
      * Wrapper for {@link #initNewAccountJni()}.
      * To be called before any other API call.
-     * @return true if init succeed, false otherwise.
+     * @exception OlmException the failure reason
      */
-    private boolean initNewAccount() {
-        mNativeId = initNewAccountJni();
-        return (0 != mNativeId);
+    private void initNewAccount() throws OlmException {
+        try {
+            mNativeId = initNewAccountJni();
+        } catch (Exception e) {
+            throw new OlmException(OlmException.EXCEPTION_CODE_INIT_ACCOUNT_CREATION, e.getMessage());
+        }
     }
 
     /**
@@ -147,10 +148,19 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
      *  "ed25519":"+v8SOlOASFTMrX3MCKBM4iVnYoZ+JIjpNt1fi8Z9O2I"
      * }</tt>
      * @return identity keys dictionary if operation succeeds, null otherwise
+     * @exception OlmException the failure reason
      */
-    public Map<String, String> identityKeys() {
+    public Map<String, String> identityKeys() throws OlmException {
         JSONObject identityKeysJsonObj = null;
-        byte[] identityKeysBuffer = identityKeysJni();
+
+        byte[] identityKeysBuffer;
+
+        try {
+            identityKeysBuffer = identityKeysJni();
+        } catch (Exception e) {
+            Log.e(LOG_TAG, "## identityKeys(): Failure - " + e.getMessage());
+            throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_IDENTITY_KEYS, e.getMessage());
+        }
 
         if (null != identityKeysBuffer) {
             try {
@@ -165,6 +175,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
 
         return toStringMap(identityKeysJsonObj);
     }
+
     /**
      * Get the public identity keys (Ed25519 fingerprint key and Curve25519 identity key).<br>
      * Keys are Base64 encoded.
@@ -180,6 +191,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
     public long maxOneTimeKeys() {
         return maxOneTimeKeysJni();
     }
+
     private native long maxOneTimeKeysJni();
 
     /**
@@ -187,12 +199,17 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
      * by this account exceeds {@link #maxOneTimeKeys()}, the old keys are discarded.<br>
      * The corresponding keys are retrieved by {@link #oneTimeKeys()}.
      * @param aNumberOfKeys number of keys to generate
-     * @return 0 if operation succeed, -1 otherwise
+     * @exception OlmException the failure reason
      */
-    public int generateOneTimeKeys(int aNumberOfKeys) {
-        return generateOneTimeKeysJni(aNumberOfKeys);
+    public void generateOneTimeKeys(int aNumberOfKeys) throws OlmException {
+        try {
+            generateOneTimeKeysJni(aNumberOfKeys);
+        } catch (Exception e) {
+            throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_GENERATE_ONE_TIME_KEYS, e.getMessage());
+        }
     }
-    private native int generateOneTimeKeysJni(int aNumberOfKeys);
+
+    private native void generateOneTimeKeysJni(int aNumberOfKeys);
 
     /**
      * Return the "one time keys" in a dictionary.<br>
@@ -207,11 +224,18 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
      * }</tt><br>
      * Public API for {@link #oneTimeKeysJni()}.<br>
      * Note: these keys are to be published on the server.
-     * @return one time keys in string dictionary if operation succeed, null otherwise
+     * @return one time keys in string dictionary.
+     * @exception OlmException the failure reason
      */
-    public Map<String, Map<String, String>> oneTimeKeys() {
+    public Map<String, Map<String, String>> oneTimeKeys() throws OlmException {
         JSONObject oneTimeKeysJsonObj = null;
-        byte[] oneTimeKeysBuffer = oneTimeKeysJni();
+        byte[] oneTimeKeysBuffer;
+
+        try {
+            oneTimeKeysBuffer = oneTimeKeysJni();
+        } catch (Exception e) {
+            throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_ONE_TIME_KEYS, e.getMessage());
+        }
 
         if( null != oneTimeKeysBuffer) {
             try {
@@ -226,6 +250,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
 
         return toStringMapMap(oneTimeKeysJsonObj);
     }
+
     /**
      * Get the public parts of the unpublished "one time keys" for the account.<br>
      * The returned data is a JSON-formatted object with the single property
@@ -238,62 +263,67 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
     /**
      * Remove the "one time keys" that the session used from the account.
      * @param aSession session instance
-     * @return 0 if operation succeed, 1 if no matching keys in the sessions to be removed, -1 if operation failed
+     * @return true if the operation succeeded.
+     * @throws OlmException the failure reason
      */
-    public int removeOneTimeKeysForSession(OlmSession aSession) {
-        int retCode = -1;
+    public boolean removeOneTimeKeys(OlmSession aSession) throws OlmException {
+        boolean res = false;
 
-        if(null != aSession) {
-            retCode = removeOneTimeKeysForSessionJni(aSession.getOlmSessionId());
-            Log.d(LOG_TAG,"## removeOneTimeKeysForSession(): result="+retCode);
+        if (null != aSession) {
+            try {
+                res = (removeOneTimeKeysJni(aSession.getOlmSessionId()) >= 0);
+                Log.d(LOG_TAG,"## removeOneTimeKeysForSession(): result=" + res);
+            } catch (Exception e) {
+                throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS, e.getMessage());
+            }
         }
 
-        return retCode;
+        return res;
     }
+
     /**
      * Remove the "one time keys" that the session used from the account.
      * @param aNativeOlmSessionId native session instance identifier
      * @return 0 if operation succeed, 1 if no matching keys in the sessions to be removed, -1 if operation failed
      */
-    private native int removeOneTimeKeysForSessionJni(long aNativeOlmSessionId);
+    private native int removeOneTimeKeysJni(long aNativeOlmSessionId);
 
     /**
      * Marks the current set of "one time keys" as being published.
-     * @return 0 if operation succeed, -1 otherwise
+     * @exception OlmException the failure reason
      */
-    public int markOneTimeKeysAsPublished() {
-        return markOneTimeKeysAsPublishedJni();
+    public void markOneTimeKeysAsPublished() throws OlmException {
+        try {
+            markOneTimeKeysAsPublishedJni();
+        } catch (Exception e) {
+            throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_MARK_ONE_KEYS_AS_PUBLISHED, e.getMessage());
+        }
     }
-    private native int markOneTimeKeysAsPublishedJni();
+
+    private native void markOneTimeKeysAsPublishedJni();
 
     /**
      * Sign a message with the ed25519 fingerprint key for this account.<br>
      * The signed message is returned by the method.
      * @param aMessage message to sign
-     * @return the signed message if operation succeed, null otherwise
+     * @return the signed message
      */
-    public String signMessage(String aMessage) {
+    public String signMessage(String aMessage) throws OlmException {
         String result = null;
 
         if (null != aMessage) {
-            byte[] utf8String = null;
-
             try {
-                utf8String = aMessage.getBytes("UTF-8");
-            } catch (Exception e) {
-                Log.e(LOG_TAG, "## signMessage(): failed =" + e.getMessage());
-            }
+                byte[] utf8String = aMessage.getBytes("UTF-8");
 
-            if (null != utf8String) {
-                byte[] signedMessage = signMessageJni(utf8String);
+                if (null != utf8String) {
+                    byte[] signedMessage = signMessageJni(utf8String);
 
-                if (null != signedMessage) {
-                    try {
+                    if (null != signedMessage) {
                         result = new String(signedMessage, "UTF-8");
-                    } catch (Exception e) {
-                        Log.e(LOG_TAG, "## signMessage(): failed =" + e.getMessage());
                     }
                 }
+            } catch (Exception e) {
+                throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_SIGN_MESSAGE, e.getMessage());
             }
         }
 
@@ -407,7 +437,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
         } else {
             aErrorMsg.setLength(0);
             try {
-                pickleRetValue = new String(serializeJni(aKey.getBytes("UTF-8"), aErrorMsg), "UTF-8");
+                pickleRetValue = new String(serializeJni(aKey.getBytes("UTF-8")), "UTF-8");
             } catch (Exception e) {
                 Log.e(LOG_TAG, "## serialize() failed " + e.getMessage());
                 aErrorMsg.append(e.getMessage());
@@ -417,7 +447,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
         return pickleRetValue;
     }
 
-    private native byte[] serializeJni(byte[] aKey, StringBuffer aErrorMsg);
+    private native byte[] serializeJni(byte[] aKey);
 
     /**
      * Loads an account from a pickled base64 string.<br>
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
index 0cb06fa20cd40f61ae75106e836afd1bb1d8e400..a04286b6400dd37dff970dfbbd5479bac70bf97c 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
@@ -39,6 +39,13 @@ public class OlmException extends IOException {
     public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_SERIALIZATION = 12;
     public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_DESERIALIZATION = 13;
 
+    public static final int EXCEPTION_CODE_ACCOUNT_IDENTITY_KEYS = 20;
+    public static final int EXCEPTION_CODE_ACCOUNT_GENERATE_ONE_TIME_KEYS = 21;
+    public static final int EXCEPTION_CODE_ACCOUNT_ONE_TIME_KEYS = 22;
+    public static final int EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS = 23;
+    public static final int EXCEPTION_CODE_ACCOUNT_MARK_ONE_KEYS_AS_PUBLISHED = 24;
+    public static final int EXCEPTION_CODE_ACCOUNT_SIGN_MESSAGE = 25;
+
     // exception human readable messages
     public static final String EXCEPTION_MSG_NEW_OUTBOUND_GROUP_SESSION = "createNewSession() failed";
     public static final String EXCEPTION_MSG_NEW_INBOUND_GROUP_SESSION = "createNewSession() failed";
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp
index d57e55b93119497d5fd0581d0cb1c6fe54b59b9f..bac8b343a5c90a2ec2c674f62144b138d2a8962c 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp
@@ -82,16 +82,18 @@ JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(releaseAccountJni)(JNIEnv *env, jobject thiz
 * Initialize a new account and return it to JAVA side.<br>
 * Since a C prt is returned as a jlong, special care will be taken
 * to make the cast (OlmAccount* => jlong) platform independent.
-* @return the initialized OlmAccount* instance if init succeed, NULL otherwise
+* @return the initialized OlmAccount* instance
 **/
 JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(initNewAccountJni)(JNIEnv *env, jobject thiz)
 {
+    const char* errorMessage = NULL;
     OlmAccount *accountPtr = initializeAccountMemory();
 
     // init account memory allocation
     if (!accountPtr)
     {
         LOGE("## initNewAccount(): failure - init account OOM");
+        errorMessage = "init account OOM";
     }
     else
     {
@@ -107,6 +109,7 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(initNewAccountJni)(JNIEnv *env, jobject thi
         if ((0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize))
         {
             LOGE("## initNewAccount(): failure - random buffer init");
+            errorMessage = "random buffer init";
         }
         else
         {
@@ -116,6 +119,7 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(initNewAccountJni)(JNIEnv *env, jobject thi
             if (accountRetCode == olm_error())
             {
                 LOGE("## initNewAccount(): failure - account creation failed Msg=%s", olm_account_last_error(accountPtr));
+                errorMessage = olm_account_last_error(accountPtr);
             }
 
             LOGD("## initNewAccount(): success - OLM account created");
@@ -128,6 +132,11 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(initNewAccountJni)(JNIEnv *env, jobject thi
         }
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return (jlong)(intptr_t)accountPtr;
 }
 
@@ -141,12 +150,14 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(initNewAccountJni)(JNIEnv *env, jobject thi
 **/
 JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject thiz)
 {
+    const char* errorMessage = NULL;
     jbyteArray byteArrayRetValue = NULL;
     OlmAccount* accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);
 
     if (!accountPtr)
     {
         LOGE("## identityKeys(): failure - invalid Account ptr=NULL");
+        errorMessage = "invalid Account ptr";
     }
     else
     {
@@ -159,6 +170,7 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject
         if (!identityKeysBytesPtr)
         {
             LOGE("## identityKeys(): failure - identity keys array OOM");
+            errorMessage = "identity keys array OOM";
         }
         else
         {
@@ -167,7 +179,8 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject
 
             if (keysResult == olm_error())
             {
-                LOGE("## identityKeys(): failure - error getting identity keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
+                errorMessage = (const char *)olm_account_last_error(accountPtr);
+                LOGE("## identityKeys(): failure - error getting identity keys Msg=%s", errorMessage);
             }
             else
             {
@@ -177,6 +190,7 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject
                 if (!byteArrayRetValue)
                 {
                     LOGE("## identityKeys(): failure - return byte array OOM");
+                    errorMessage = "byte array OOM";
                 }
                 else
                 {
@@ -189,6 +203,11 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject
         }
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return byteArrayRetValue;
 }
 
@@ -221,16 +240,16 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(maxOneTimeKeysJni)(JNIEnv *env, jobject thi
 /**
  * Generate "one time keys".
  * @param aNumberOfKeys number of keys to generate
- * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise
 **/
-JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject thiz, jint aNumberOfKeys)
+JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject thiz, jint aNumberOfKeys)
 {
+    const char* errorMessage = NULL;
     OlmAccount *accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);
-    jint retCode = ERROR_CODE_KO;
 
     if (!accountPtr)
     {
         LOGE("## generateOneTimeKeysJni(): failure - invalid Account ptr");
+        errorMessage = "invalid Account ptr";
     }
     else
     {
@@ -243,6 +262,7 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject
         if ((0 != randomLength) && !setRandomInBuffer(env, &randomBufferPtr, randomLength))
         {
             LOGE("## generateOneTimeKeysJni(): failure - random buffer init");
+            errorMessage = "random buffer init";
         }
         else
         {
@@ -251,12 +271,13 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject
             // retrieve key pairs in keysBytesPtr
             size_t result = olm_account_generate_one_time_keys(accountPtr, (size_t)aNumberOfKeys, (void*)randomBufferPtr, randomLength);
 
-            if (result == olm_error()) {
-                LOGE("## generateOneTimeKeysJni(): failure - error generating one time keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
+            if (result == olm_error())
+            {
+                errorMessage = olm_account_last_error(accountPtr);
+                LOGE("## generateOneTimeKeysJni(): failure - error generating one time keys Msg=%s", errorMessage);
             }
             else
             {
-                retCode = ERROR_CODE_OK;
                 LOGD("## generateOneTimeKeysJni(): success - result=%lu", static_cast<long unsigned int>(result));
             }
         }
@@ -268,7 +289,10 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject
         }
     }
 
-    return retCode;
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
 }
 
 /**
@@ -278,6 +302,7 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject
 **/
 JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject thiz)
 {
+    const char* errorMessage = NULL;
     jbyteArray byteArrayRetValue = NULL;
     OlmAccount* accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);
 
@@ -286,6 +311,7 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject t
     if (!accountPtr)
     {
         LOGE("## oneTimeKeysJni(): failure - invalid Account ptr");
+        errorMessage = "invalid Account ptr";
     }
     else
     {
@@ -296,13 +322,16 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject t
         if (!keysBytesPtr)
         {
             LOGE("## oneTimeKeysJni(): failure - one time keys array OOM");
+            errorMessage = "one time keys array OOM";
         }
         else
         {
             // retrieve key pairs in keysBytesPtr
             size_t keysResult = olm_account_one_time_keys(accountPtr, keysBytesPtr, keysLength);
+
             if (keysResult == olm_error()) {
                 LOGE("## oneTimeKeysJni(): failure - error getting one time keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
+                errorMessage = (const char *)olm_account_last_error(accountPtr);
             }
             else
             {
@@ -312,6 +341,7 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject t
                 if (!byteArrayRetValue)
                 {
                     LOGE("## oneTimeKeysJni(): failure - return byte array OOM");
+                    errorMessage = "return byte array OOM";
                 }
                 else
                 {
@@ -324,6 +354,11 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject t
         }
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return byteArrayRetValue;
 }
 
@@ -331,21 +366,24 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject t
  * Remove the "one time keys"  that the session used from the account.
  * Return the public parts of the unpublished "one time keys" for the account
  * @param aNativeOlmSessionId session instance
- * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_NO_MATCHING_ONE_TIME_KEYS if no matching keys, ERROR_CODE_KO otherwise
+ * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise
 **/
-JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysForSessionJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId)
+JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId)
 {
+    const char* errorMessage = NULL;
     jint retCode = ERROR_CODE_KO;
     OlmAccount* accountPtr = NULL;
     OlmSession* sessionPtr = (OlmSession*)aNativeOlmSessionId;
 
     if (!sessionPtr)
     {
-        LOGE("## removeOneTimeKeysForSessionJni(): failure - invalid session ptr");
+        LOGE("## removeOneTimeKeysJni(): failure - invalid session ptr");
+        errorMessage = "invalid session ptr";
     }
     else if(!(accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
     {
-        LOGE("## removeOneTimeKeysForSessionJni(): failure - invalid account ptr");
+        LOGE("## removeOneTimeKeysJni(): failure - invalid account ptr");
+        errorMessage = "invalid account ptr";
     }
     else
     {
@@ -353,33 +391,36 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysForSessionJni)(JNIEnv *env,
 
         if (result == olm_error())
         {   // the account doesn't have any matching "one time keys"..
-            LOGW("## removeOneTimeKeysForSessionJni(): failure - removing one time keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
-
-            retCode = ERROR_CODE_NO_MATCHING_ONE_TIME_KEYS;
+            LOGW("## removeOneTimeKeysJni(): failure - removing one time keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
+            errorMessage = (const char *)olm_account_last_error(accountPtr);
         }
         else
         {
             retCode = ERROR_CODE_OK;
-            LOGD("## removeOneTimeKeysForSessionJni(): success");
+            LOGD("## removeOneTimeKeysJni(): success");
         }
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return retCode;
 }
 
 /**
  * Mark the current set of "one time keys" as being published.
- * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise
 **/
-JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz)
+JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz)
 {
-    jint retCode = ERROR_CODE_OK;
+    const char* errorMessage = NULL;
     OlmAccount* accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);
 
     if (!accountPtr)
     {
         LOGE("## markOneTimeKeysAsPublishedJni(): failure - invalid account ptr");
-        retCode = ERROR_CODE_KO;
+        errorMessage = "invalid account ptr";
     }
     else
     {
@@ -388,7 +429,7 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env,
         if (result == olm_error())
         {
             LOGW("## markOneTimeKeysAsPublishedJni(): failure - Msg=%s",(const char *)olm_account_last_error(accountPtr));
-            retCode = ERROR_CODE_KO;
+            errorMessage = (const char *)olm_account_last_error(accountPtr);
         }
         else
         {
@@ -396,7 +437,10 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env,
         }
     }
 
-    return retCode;
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
 }
 
 /**
@@ -407,16 +451,19 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env,
 **/
 JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage)
 {
+    const char* errorMessage = NULL;
     OlmAccount* accountPtr = NULL;
     jbyteArray signedMsgRetValueBuffer = NULL;
 
     if (!aMessage)
     {
         LOGE("## signMessageJni(): failure - invalid aMessage param");
+        errorMessage = "invalid aMessage param";
     }
     else if(!(accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
     {
         LOGE("## signMessageJni(): failure - invalid account ptr");
+        errorMessage = "invalid account ptr";
     }
     else
     {
@@ -431,6 +478,7 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject t
         if (!signedMsgPtr)
         {
             LOGE("## signMessageJni(): failure - signature allocation OOM");
+            errorMessage = "signature allocation OOM";
         }
         else
         {
@@ -444,6 +492,7 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject t
             if (resultSign == olm_error())
             {
                 LOGE("## signMessageJni(): failure - error signing message Msg=%s",(const char *)olm_account_last_error(accountPtr));
+                errorMessage = (const char *)olm_account_last_error(accountPtr);
             }
             else
             {
@@ -467,21 +516,23 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject t
         }
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return signedMsgRetValueBuffer;
 }
 
 /**
 * Serialize and encrypt account instance into a base64 string.<br>
 * @param aKeyBuffer key used to encrypt the serialized account data
-* @param[out] aErrorMsg error message set if operation failed
 * @return a base64 string if operation succeed, null otherwise
 **/
-JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer, jobject aErrorMsg)
+JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer)
 {
+    const char* errorMessage = NULL;
     jbyteArray pickledDataRetValue = 0;
-    jclass errorMsgJClass = 0;
-    jmethodID errorMsgMethodId = 0;
-    jstring errorJstring = 0;
     jbyte* keyPtr = NULL;
     OlmAccount* accountPtr = NULL;
 
@@ -490,26 +541,17 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
     if (!aKeyBuffer)
     {
         LOGE(" ## serializeJni(): failure - invalid key");
-    }
-    else if (!aErrorMsg)
-    {
-        LOGE(" ## serializeJni(): failure - invalid error object");
+        errorMessage = "invalid key";
     }
     else if (!(accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
     {
        LOGE(" ## serializeJni(): failure - invalid account ptr");
-    }
-    else if (!(errorMsgJClass = env->GetObjectClass(aErrorMsg)))
-    {
-        LOGE(" ## serializeJni(): failure - unable to get error class");
-    }
-    else if (!(errorMsgMethodId = env->GetMethodID(errorMsgJClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;")))
-    {
-        LOGE(" ## serializeJni(): failure - unable to get error method ID");
+       errorMessage = "invalid account ptr";
     }
     else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, NULL)))
     {
         LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM");
+        errorMessage = "keyPtr JNI allocation OOM";
     }
     else
     {
@@ -523,6 +565,7 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
         if (!pickledPtr)
         {
             LOGE(" ## serializeJni(): failure - pickledPtr buffer OOM");
+            errorMessage = "pickledPtr buffer OOM";
         }
         else
         {
@@ -533,13 +576,8 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
                                                pickledLength);
             if (result == olm_error())
             {
-                const char *errorMsgPtr = olm_account_last_error(accountPtr);
-                LOGE(" ## serializeJni(): failure - olm_pickle_account() Msg=%s",errorMsgPtr);
-
-                if(0 != (errorJstring = env->NewStringUTF(errorMsgPtr)))
-                {
-                    env->CallObjectMethod(aErrorMsg, errorMsgMethodId, errorJstring);
-                }
+                errorMessage = olm_account_last_error(accountPtr);
+                LOGE(" ## serializeJni(): failure - olm_pickle_account() Msg=%s", errorMessage);
             }
             else
             {
@@ -562,6 +600,11 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
         env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return pickledDataRetValue;
 }
 
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.h
index 94a038134a1f2a85e6c743956d9a2204eebd1141..5b73acdb85e0c54433c20fcaf90e7c2ebf8fb2ba 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.h
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.h
@@ -39,15 +39,15 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject
 // one time keys
 JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject thiz);
 JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(maxOneTimeKeysJni)(JNIEnv *env, jobject thiz);
-JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject thiz, jint aNumberOfKeys);
-JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysForSessionJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId);
-JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz);
+JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject thiz, jint aNumberOfKeys);
+JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId);
+JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz);
 
 // signing
 JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage);
 
 // serialization
-JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer, jobject aErrorMsg);
+JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer);
 JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedDataBuffer, jbyteArray aKeyBuffer);
 
 #ifdef __cplusplus
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h
index f1d124e37b09cb294e0fae88b480e12c4a74e95a..1c80388db26935bd26a91247a5496377cac2c90c 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h
@@ -55,7 +55,6 @@ namespace AndroidOlmSdk
 {
     // Error codes definition
     static const int ERROR_CODE_OK = 0;
-    static const int ERROR_CODE_NO_MATCHING_ONE_TIME_KEYS = ERROR_CODE_OK+1;
     static const int ERROR_CODE_KO = -1;
 
     // constants