| // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'dart:io'; | |
| import 'package:meta/meta.dart' show internal; | |
| import 'third_party/generated_bindings.dart'; | |
| // TODO(#567): Add the fact that [JException] is now a [JObject] to the | |
| // CHANGELOG. | |
| mixin _ExplainsRelease on StateError { | |
| String? get releaseStackTrace; | |
| @override | |
| String toString() { | |
| final sb = StringBuffer(super.toString()); | |
| if (releaseStackTrace != null) { | |
| sb.write('\n'); | |
| sb.write(releaseStackTrace); | |
| } else { | |
| sb.writeln('\nTo see where the object was released, ' | |
| 'set `Jni.captureStackTraceOnRelease = true`.'); | |
| } | |
| return sb.toString(); | |
| } | |
| } | |
| final class UseAfterReleaseError extends StateError with _ExplainsRelease { | |
| @override | |
| final String? releaseStackTrace; | |
| UseAfterReleaseError([this.releaseStackTrace]) | |
| : super('Use after release error'); | |
| } | |
| // TODO(#567): Use NullPointerError once it's available. | |
| final class JNullError extends StateError { | |
| JNullError() : super('The reference was null'); | |
| } | |
| final class NoSuchMethodError extends StateError { | |
| final String name; | |
| NoSuchMethodError(this.name) : super('No such method or field: $name'); | |
| } | |
| final class DoubleReleaseError extends StateError with _ExplainsRelease { | |
| @override | |
| final String? releaseStackTrace; | |
| DoubleReleaseError([this.releaseStackTrace]) : super('Double release error'); | |
| } | |
| /// Represents JNI errors that might be returned by methods like `CreateJavaVM`. | |
| sealed class JniError extends Error { | |
| static const _errors = { | |
| JniErrorCode.ERR: JniGenericError.new, | |
| JniErrorCode.EDETACHED: JniThreadDetachedError.new, | |
| JniErrorCode.EVERSION: JniVersionError.new, | |
| JniErrorCode.ENOMEM: JniOutOfMemoryError.new, | |
| JniErrorCode.EEXIST: JniVmExistsError.new, | |
| JniErrorCode.EINVAL: JniArgumentError.new, | |
| }; | |
| final String message; | |
| JniError(this.message); | |
| @internal | |
| factory JniError.of(JniErrorCode status) { | |
| if (!_errors.containsKey(status)) { | |
| status = JniErrorCode.ERR; | |
| } | |
| return _errors[status]!(); | |
| } | |
| @override | |
| String toString() { | |
| return 'JniError: $message'; | |
| } | |
| } | |
| final class JniGenericError extends JniError { | |
| JniGenericError() : super('Generic JNI error'); | |
| } | |
| final class JniThreadDetachedError extends JniError { | |
| JniThreadDetachedError() : super('Thread detached from VM'); | |
| } | |
| final class JniVersionError extends JniError { | |
| JniVersionError() : super('JNI version error'); | |
| } | |
| final class JniOutOfMemoryError extends JniError { | |
| JniOutOfMemoryError() : super('Out of memory'); | |
| } | |
| final class JniVmExistsError extends JniError { | |
| JniVmExistsError() : super('VM Already created'); | |
| } | |
| final class JniArgumentError extends JniError { | |
| JniArgumentError() : super('Invalid arguments'); | |
| } | |
| final class NoJvmInstanceError extends Error { | |
| @override | |
| String toString() => 'No JNI instance is available'; | |
| } | |
| final class HelperNotFoundError extends Error { | |
| final String path; | |
| HelperNotFoundError(this.path); | |
| @override | |
| String toString() => ''' | |
| Unable to locate the helper library. | |
| Ensure that the helper library is available at the path: $path | |
| Run `dart jni:setup` to generate the shared library if it does not exist. | |
| Note: If the --build-path option is passed to jni:setup, Jni.spawn must be | |
| called with same dylibDir. Also when creating new Dart isolates, Jni.setDylibDir | |
| must be called. | |
| '''; | |
| } | |
| final class DynamicLibraryLoadError extends Error { | |
| final String libraryPath; | |
| DynamicLibraryLoadError(this.libraryPath); | |
| @override | |
| String toString() { | |
| return ''' | |
| Failed to load dynamic library at path: $libraryPath | |
| The library was found at the specified path, but it could not be loaded. | |
| This might be due to missing dependencies or incorrect file permissions. | |
| Please ensure ${Platform.isWindows ? r'that `\bin\server\jvm.dll` is in the PATH, and ' : ''}that the file has the correct permissions. | |
| '''; | |
| } | |
| } | |
| final class JniNewStringException implements Exception { | |
| final String string; | |
| JniNewStringException(this.string); | |
| @override | |
| String toString() => 'Failed to convert string to a JString: $string'; | |
| } |