blob: 701953ba40b21455960d248201ef21c21beedb43 [file] [log] [blame] [edit]
// 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.
final class UseAfterReleaseError extends StateError {
UseAfterReleaseError() : 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 DoubleReleaseError extends StateError {
DoubleReleaseError() : 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';
}
// TODO(#567): Remove this class in favor of `JThrowable`.
class JniException implements Exception {
/// Error message from Java exception.
final String message;
/// Stack trace from Java.
final String stackTrace;
JniException(this.message, this.stackTrace);
@override
String toString() => 'Exception in Java code called through JNI: '
'$message\n\n$stackTrace\n';
}
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.
''';
}
}