Reland Use controller exception in Java controller (#26802)

* Revert "Revert "Use controller exception in Java controller (#26708)" (#26799)"

This reverts commit bf9596758f539c628c915940086e6d0f519573ee.

* fix the type inside cluster exception

* Add missing L  fully-qualified-class for controller exception
diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt
index c4b870d..b2faca8 100644
--- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt
+++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt
@@ -57,7 +57,7 @@
   }
 
   private inner class InternalResubscriptionAttemptCallback : ResubscriptionAttemptCallback {
-    override fun onResubscriptionAttempt(terminationCause: Int, nextResubscribeIntervalMsec: Int) {
+    override fun onResubscriptionAttempt(terminationCause: Long, nextResubscribeIntervalMsec: Long) {
       logger.log(Level.INFO, "ResubscriptionAttemptCallback");
     }
   }
diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/MatterError.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/MatterError.java
index e669a7b..ac12eac 100644
--- a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/MatterError.java
+++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/MatterError.java
@@ -20,15 +20,15 @@
 import java.util.Objects;
 
 public class MatterError {
-  private int errorCode;
+  private long errorCode;
   private String errorMessage;
 
   public static final MatterError DISCOVERY_SERVICE_LOST =
-      new MatterError(4, "Discovery service was lost.");
+      new MatterError(4L, "Discovery service was lost.");
 
   public static final MatterError NO_ERROR = new MatterError(0, null);
 
-  public MatterError(int errorCode, String errorMessage) {
+  public MatterError(long errorCode, String errorMessage) {
     this.errorCode = errorCode;
     this.errorMessage = errorMessage;
   }
@@ -37,7 +37,7 @@
     return this.equals(NO_ERROR);
   }
 
-  public int getErrorCode() {
+  public long getErrorCode() {
     return errorCode;
   }
 
diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp
index d004de1..a84bd92 100644
--- a/src/controller/java/AndroidCallbacks.cpp
+++ b/src/controller/java/AndroidCallbacks.cpp
@@ -16,6 +16,7 @@
  */
 #include "AndroidCallbacks.h"
 #include <controller/java/AndroidClusterExceptions.h>
+#include <controller/java/AndroidControllerExceptions.h>
 #include <controller/java/CHIPAttributeTLVValueDecoder.h>
 #include <controller/java/CHIPEventTLVValueDecoder.h>
 #include <jni.h>
@@ -105,16 +106,14 @@
     JniReferences::GetInstance().FindMethod(env, javaCallback, "onConnectionFailure", "(JLjava/lang/Exception;)V", &failureMethod);
     VerifyOrReturn(failureMethod != nullptr, ChipLogError(Controller, "Could not find onConnectionFailure method"));
 
-    // Create the exception to return.
-    jclass controllerExceptionCls;
-    CHIP_ERROR err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipDeviceControllerException",
-                                                              controllerExceptionCls);
-    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find exception type for onConnectionFailure"));
-    JniClass controllerExceptionJniCls(controllerExceptionCls);
-
-    jmethodID exceptionConstructor = env->GetMethodID(controllerExceptionCls, "<init>", "(ILjava/lang/String;)V");
-    jobject exception =
-        env->NewObject(controllerExceptionCls, exceptionConstructor, error.AsInteger(), env->NewStringUTF(ErrorStr(error)));
+    jthrowable exception;
+    CHIP_ERROR err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, ErrorStr(error),
+                                                                                                 error.AsInteger(), exception);
+    VerifyOrReturn(
+        err == CHIP_NO_ERROR,
+        ChipLogError(Controller,
+                     "Unable to create AndroidControllerException on GetConnectedDeviceCallback::OnDeviceConnectionFailureFn: %s",
+                     ErrorStr(err)));
 
     DeviceLayer::StackUnlock unlock;
     env->CallVoidMethod(javaCallback, failureMethod, peerId.GetNodeId(), exception);
@@ -558,12 +557,12 @@
 
     jmethodID onResubscriptionAttemptMethod;
     ReturnLogErrorOnFailure(JniReferences::GetInstance().FindMethod(
-        env, mResubscriptionAttemptCallbackRef, "onResubscriptionAttempt", "(II)V", &onResubscriptionAttemptMethod));
+        env, mResubscriptionAttemptCallbackRef, "onResubscriptionAttempt", "(JJ)V", &onResubscriptionAttemptMethod));
 
     DeviceLayer::StackUnlock unlock;
     env->CallVoidMethod(mResubscriptionAttemptCallbackRef, onResubscriptionAttemptMethod,
-                        static_cast<jint>(aTerminationCause.AsInteger()),
-                        static_cast<jint>(apReadClient->ComputeTimeTillNextSubscription()));
+                        static_cast<jlong>(aTerminationCause.AsInteger()),
+                        static_cast<jlong>(apReadClient->ComputeTimeTillNextSubscription()));
     VerifyOrReturnError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
     return CHIP_NO_ERROR;
 }
@@ -585,8 +584,10 @@
     JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
 
     jthrowable exception;
-    err = AndroidClusterExceptions::GetInstance().CreateIllegalStateException(env, message, errorCode, exception);
-    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create IllegalStateException: %s", ErrorStr(err)));
+    err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, message, errorCode, exception);
+    VerifyOrReturn(
+        err == CHIP_NO_ERROR,
+        ChipLogError(Controller, "Unable to create AndroidControllerException on ReportCallback::ReportError: %s", ErrorStr(err)));
 
     jmethodID onErrorMethod;
     err = JniReferences::GetInstance().FindMethod(
@@ -813,12 +814,12 @@
 
     jmethodID onResubscriptionAttemptMethod;
     ReturnLogErrorOnFailure(JniReferences::GetInstance().FindMethod(
-        env, mResubscriptionAttemptCallbackRef, "onResubscriptionAttempt", "(II)V", &onResubscriptionAttemptMethod));
+        env, mResubscriptionAttemptCallbackRef, "onResubscriptionAttempt", "(JJ)V", &onResubscriptionAttemptMethod));
 
     DeviceLayer::StackUnlock unlock;
     env->CallVoidMethod(mResubscriptionAttemptCallbackRef, onResubscriptionAttemptMethod,
-                        static_cast<jint>(aTerminationCause.AsInteger()),
-                        static_cast<jint>(apReadClient->ComputeTimeTillNextSubscription()));
+                        static_cast<jlong>(aTerminationCause.AsInteger()),
+                        static_cast<jlong>(apReadClient->ComputeTimeTillNextSubscription()));
 
     return CHIP_NO_ERROR;
 }
@@ -839,8 +840,10 @@
     JNIEnv * env   = JniReferences::GetInstance().GetEnvForCurrentThread();
 
     jthrowable exception;
-    err = AndroidClusterExceptions::GetInstance().CreateIllegalStateException(env, message, errorCode, exception);
-    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create IllegalStateException: %s", ErrorStr(err)));
+    err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, message, errorCode, exception);
+    VerifyOrReturn(err == CHIP_NO_ERROR,
+                   ChipLogError(Controller, "Unable to create AndroidControllerException: %s on eportEventCallback::ReportError",
+                                ErrorStr(err)));
 
     jmethodID onErrorMethod;
     err = JniReferences::GetInstance().FindMethod(
@@ -943,8 +946,11 @@
 
     ChipLogError(Controller, "WriteAttributesCallback ReportError is called");
     jthrowable exception;
-    err = AndroidClusterExceptions::GetInstance().CreateIllegalStateException(env, message, errorCode, exception);
-    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create IllegalStateException: %s", ErrorStr(err)));
+    err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, message, errorCode, exception);
+    VerifyOrReturn(err == CHIP_NO_ERROR,
+                   ChipLogError(Controller,
+                                "Unable to create AndroidControllerException on WriteAttributesCallback::ReportError: %s",
+                                ErrorStr(err)));
 
     jmethodID onErrorMethod;
     err = JniReferences::GetInstance().FindMethod(env, mJavaCallbackRef, "onError",
@@ -1043,8 +1049,10 @@
 
     ChipLogError(Controller, "InvokeCallback ReportError is called");
     jthrowable exception;
-    err = AndroidClusterExceptions::GetInstance().CreateIllegalStateException(env, message, errorCode, exception);
-    VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create IllegalStateException: %s", ErrorStr(err)));
+    err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, message, errorCode, exception);
+    VerifyOrReturn(
+        err == CHIP_NO_ERROR,
+        ChipLogError(Controller, "Unable to create AndroidControllerException: %s on InvokeCallback::ReportError", ErrorStr(err)));
 
     jmethodID onErrorMethod;
     err = JniReferences::GetInstance().FindMethod(env, mJavaCallbackRef, "onError", "(Ljava/lang/Exception;)V", &onErrorMethod);
diff --git a/src/controller/java/AndroidClusterExceptions.cpp b/src/controller/java/AndroidClusterExceptions.cpp
index a858a4b..4a75758 100644
--- a/src/controller/java/AndroidClusterExceptions.cpp
+++ b/src/controller/java/AndroidClusterExceptions.cpp
@@ -1,6 +1,6 @@
 /*
  *
- *    Copyright (c) 2021 Project CHIP Authors
+ *    Copyright (c) 2021-2023 Project CHIP Authors
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
 
 namespace chip {
 
-CHIP_ERROR AndroidClusterExceptions::CreateChipClusterException(JNIEnv * env, jint errorCode, jthrowable & outEx)
+CHIP_ERROR AndroidClusterExceptions::CreateChipClusterException(JNIEnv * env, uint32_t errorCode, jthrowable & outEx)
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
     jmethodID exceptionConstructor;
@@ -34,10 +34,10 @@
     VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
     chip::JniClass clusterExceptionJniCls(clusterExceptionCls);
 
-    exceptionConstructor = env->GetMethodID(clusterExceptionCls, "<init>", "(I)V");
+    exceptionConstructor = env->GetMethodID(clusterExceptionCls, "<init>", "(J)V");
     VerifyOrReturnError(exceptionConstructor != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
 
-    outEx = (jthrowable) env->NewObject(clusterExceptionCls, exceptionConstructor, errorCode);
+    outEx = (jthrowable) env->NewObject(clusterExceptionCls, exceptionConstructor, static_cast<jlong>(errorCode));
     VerifyOrReturnError(outEx != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
 
     return err;
diff --git a/src/controller/java/AndroidClusterExceptions.h b/src/controller/java/AndroidClusterExceptions.h
index 51a3638..e0bdd07 100644
--- a/src/controller/java/AndroidClusterExceptions.h
+++ b/src/controller/java/AndroidClusterExceptions.h
@@ -1,6 +1,6 @@
 /*
  *
- *    Copyright (c) 2021 Project CHIP Authors
+ *    Copyright (c) 2021-2023 Project CHIP Authors
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@
     /**
      * Creates a Java ChipClusterException object in outEx.
      */
-    CHIP_ERROR CreateChipClusterException(JNIEnv * env, jint errorCode, jthrowable & outEx);
+    CHIP_ERROR CreateChipClusterException(JNIEnv * env, uint32_t errorCode, jthrowable & outEx);
 
     /**
      * Creates a Java IllegalStateException in outEx.
diff --git a/src/controller/java/AndroidControllerExceptions.cpp b/src/controller/java/AndroidControllerExceptions.cpp
new file mode 100644
index 0000000..e426759e
--- /dev/null
+++ b/src/controller/java/AndroidControllerExceptions.cpp
@@ -0,0 +1,43 @@
+/*
+ *
+ *    Copyright (c) 2023 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "AndroidControllerExceptions.h"
+
+#include <lib/core/CHIPError.h>
+#include <lib/support/CHIPJNIError.h>
+#include <lib/support/JniReferences.h>
+#include <lib/support/JniTypeWrappers.h>
+
+namespace chip {
+
+CHIP_ERROR AndroidControllerExceptions::CreateAndroidControllerException(JNIEnv * env, const char * message, uint32_t errorCode,
+                                                                         jthrowable & outEx)
+{
+    jclass controllerExceptionCls;
+    CHIP_ERROR err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipDeviceControllerException",
+                                                              controllerExceptionCls);
+    VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
+    JniClass controllerExceptionJniCls(controllerExceptionCls);
+
+    jmethodID exceptionConstructor = env->GetMethodID(controllerExceptionCls, "<init>", "(JLjava/lang/String;)V");
+    outEx = (jthrowable) env->NewObject(controllerExceptionCls, exceptionConstructor, static_cast<jlong>(errorCode),
+                                        env->NewStringUTF(message));
+    VerifyOrReturnError(outEx != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
+    return CHIP_NO_ERROR;
+}
+
+} // namespace chip
diff --git a/src/controller/java/AndroidControllerExceptions.h b/src/controller/java/AndroidControllerExceptions.h
new file mode 100644
index 0000000..02ed39d
--- /dev/null
+++ b/src/controller/java/AndroidControllerExceptions.h
@@ -0,0 +1,45 @@
+/*
+ *
+ *    Copyright (c) 2023 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#pragma once
+
+#include <jni.h>
+#include <lib/core/CHIPError.h>
+
+namespace chip {
+class AndroidControllerExceptions
+{
+public:
+    AndroidControllerExceptions(const AndroidControllerExceptions &)  = delete;
+    AndroidControllerExceptions(const AndroidControllerExceptions &&) = delete;
+    AndroidControllerExceptions & operator=(const AndroidControllerExceptions &) = delete;
+
+    static AndroidControllerExceptions & GetInstance()
+    {
+        static AndroidControllerExceptions androidControllerExceptions;
+        return androidControllerExceptions;
+    }
+
+    /**
+     * Creates a Java AndroidControllerException object in outEx.
+     */
+    CHIP_ERROR CreateAndroidControllerException(JNIEnv * env, const char * message, uint32_t errorCode, jthrowable & outEx);
+
+private:
+    AndroidControllerExceptions() {}
+};
+} // namespace chip
diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn
index 3d982bf..ece7ed0 100644
--- a/src/controller/java/BUILD.gn
+++ b/src/controller/java/BUILD.gn
@@ -41,6 +41,8 @@
     "AndroidClusterExceptions.h",
     "AndroidCommissioningWindowOpener.cpp",
     "AndroidCommissioningWindowOpener.h",
+    "AndroidControllerExceptions.cpp",
+    "AndroidControllerExceptions.h",
     "AndroidCurrentFabricRemover.cpp",
     "AndroidCurrentFabricRemover.h",
     "AndroidDeviceControllerWrapper.cpp",
diff --git a/src/controller/java/src/chip/devicecontroller/ChipClusterException.java b/src/controller/java/src/chip/devicecontroller/ChipClusterException.java
index 335c973..a9c5728 100644
--- a/src/controller/java/src/chip/devicecontroller/ChipClusterException.java
+++ b/src/controller/java/src/chip/devicecontroller/ChipClusterException.java
@@ -21,11 +21,11 @@
 public class ChipClusterException extends Exception {
   private static final long serialVersionUID = 1L;
 
-  public int errorCode;
+  public long errorCode;
 
   public ChipClusterException() {}
 
-  public ChipClusterException(int errorCode) {
+  public ChipClusterException(long errorCode) {
     super(String.format("CHIP cluster error: %d", errorCode));
     this.errorCode = errorCode;
   }
diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceControllerException.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceControllerException.java
index 2d2d583..ec7cfb7 100644
--- a/src/controller/java/src/chip/devicecontroller/ChipDeviceControllerException.java
+++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceControllerException.java
@@ -21,11 +21,11 @@
 public class ChipDeviceControllerException extends RuntimeException {
   private static final long serialVersionUID = 1L;
 
-  public int errorCode;
+  public long errorCode;
 
   public ChipDeviceControllerException() {}
 
-  public ChipDeviceControllerException(int errorCode, String message) {
+  public ChipDeviceControllerException(long errorCode, String message) {
     super(message != null ? message : String.format("Error Code %d", errorCode));
     this.errorCode = errorCode;
   }
diff --git a/src/controller/java/src/chip/devicecontroller/ResubscriptionAttemptCallback.java b/src/controller/java/src/chip/devicecontroller/ResubscriptionAttemptCallback.java
index cf029ff..01c6eaa 100644
--- a/src/controller/java/src/chip/devicecontroller/ResubscriptionAttemptCallback.java
+++ b/src/controller/java/src/chip/devicecontroller/ResubscriptionAttemptCallback.java
@@ -18,5 +18,5 @@
 package chip.devicecontroller;
 
 public interface ResubscriptionAttemptCallback {
-  void onResubscriptionAttempt(int terminationCause, int nextResubscribeIntervalMsec);
+  void onResubscriptionAttempt(long terminationCause, long nextResubscribeIntervalMsec);
 }
diff --git a/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java b/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java
index f7f9814..56494b0 100644
--- a/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java
+++ b/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java
@@ -48,10 +48,10 @@
   public void connectionFailure() {
     var callback = new FakeGetConnectedDeviceCallback();
     var jniCallback = new GetConnectedDeviceCallbackJni(callback);
-    callbackTestUtil.onDeviceConnectionFailure(jniCallback, 100);
+    callbackTestUtil.onDeviceConnectionFailure(jniCallback, 100L);
 
     assertThat(callback.error).isInstanceOf(ChipDeviceControllerException.class);
-    assertThat(((ChipDeviceControllerException) callback.error).errorCode).isEqualTo(100);
+    assertThat(((ChipDeviceControllerException) callback.error).errorCode).isEqualTo(100L);
   }
 
   class FakeGetConnectedDeviceCallback implements GetConnectedDeviceCallback {