1# Changelog
2
3All notable changes to this project will be documented in this file.
4
5The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
8<!-- Use the following sections from the spec: http://keepachangelog.com/en/1.0.0/
9  - Added for new features.
10  - Changed for changes in existing functionality.
11  - Deprecated for soon-to-be removed features.
12  - Removed for now removed features.
13  - Fixed for any bug fixes.
14  - Security in case of vulnerabilities. -->
15
16## [Unreleased]
17
18
19## [0.21.1] — 2023-03-08
20
21### Fixes
22- Compilation is fixed for architectures with a C ABI that has unsigned `char` types. ([#419](https://github.com/jni-rs/jni-rs/pull/419))
23
24## [0.21.0] — 2023-02-13
25
26This release makes extensive breaking changes in order to improve safety. Most projects that use this library will need to be changed. Please see [the migration guide](docs/0.21-MIGRATION.md).
27
28### Added
29- `JavaStr::into_raw()` which drops the `JavaStr` and releases ownership of the raw string pointer ([#374](https://github.com/jni-rs/jni-rs/pull/374))
30- `JavaStr::from_raw()` which takes ownership of a raw string pointer to create a `JavaStr` ([#374](https://github.com/jni-rs/jni-rs/pull/374))
31- `JNIEnv::get_string_unchecked` is a cheaper, `unsafe` alternative to `get_string` that doesn't check the given object is a `java.lang.String` instance. ([#328](https://github.com/jni-rs/jni-rs/issues/328))
32- `WeakRef` and `JNIEnv#new_weak_ref`. ([#304](https://github.com/jni-rs/jni-rs/pull/304))
33- `define_class_bytearray` method that takes an `AutoElements<jbyte>` rather than a `&[u8]` ([#244](https://github.com/jni-rs/jni-rs/pull/244))
34- `JObject` now has an `as_raw` method that borrows the `JObject` instead of taking ownership like `into_raw`. Needed because `JObject` no longer has the `Copy` trait. ([#392](https://github.com/jni-rs/jni-rs/issues/392))
35- `JavaVM::destroy()` (unsafe) as a way to try and unload a `JavaVM` on supported platforms ([#391](https://github.com/jni-rs/jni-rs/issues/391))
36- `JavaVM::detach_current_thread()` (unsafe) as a way to explicitly detach a thread (normally this is automatic on thread exit). Needed to detach daemon threads manually if using `JavaVM::destroy()` ([#391](https://github.com/jni-rs/jni-rs/issues/391))
37- `JPrimitiveArray<T: TypeArray>` and type-specific aliases like `JByteArray`, `JIntArray` etc now provide safe, reference wrappers for the `sys` types `jarray` and `jbyteArray` etc with a lifetime like `JObject` ([#400](https://github.com/jni-rs/jni-rs/pull/400))
38- `JObjectArray` provides a reference wrapper for a `jobjectArray` with a lifetime like `JObject`. ([#400](https://github.com/jni-rs/jni-rs/pull/400))
39- `AutoElements` and `AutoElementsCritical` (previously `AutoArray`/`AutoPrimitiveArray`) implement `Deref<Target=[T]>` and `DerefMut` so array elements can be accessed via slices without needing additional `unsafe` code. ([#400](https://github.com/jni-rs/jni-rs/pull/400))
40- `AsJArrayRaw` trait which enables `JNIEnv::get_array_length()` to work with `JPrimitiveArray` or `JObjectArray` types ([#400](https://github.com/jni-rs/jni-rs/pull/400))
41- `InitArgsBuilder` now has `try_option` and `option_encoded` methods. ([#414](https://github.com/jni-rs/jni-rs/pull/414))
42
43### Changed
44- `JNIEnv::get_string` checks that the given object is a `java.lang.String` instance to avoid undefined behaviour from the JNI implementation potentially aborting the program. ([#328](https://github.com/jni-rs/jni-rs/issues/328))
45- `JNIEnv::call_*method_unchecked` was marked `unsafe`, as passing improper argument types, or a bad number of arguments, can cause a JVM crash. ([#385](https://github.com/jni-rs/jni-rs/issues/385))
46- The `JNIEnv::new_object_unchecked` function now takes arguments as `&[jni::sys::jvalue]` to avoid allocating, putting it inline with changes to `JniEnv::call_*_unchecked` from 0.20.0 ([#382](https://github.com/jni-rs/jni-rs/pull/382))
47- The `get_superclass` function now returns an Option instead of a null pointer if the class has no superclass ([#151](https://github.com/jni-rs/jni-rs/issues/151))
48- The `invocation` feature now locates the JVM implementation dynamically at runtime (via the `java-locator` crate by default) instead of linking with the JVM at build time ([#293](https://github.com/jni-rs/jni-rs/pull/293))
49- Most `JNIEnv` methods now require `&mut self`. This improves safety by preventing `JObject`s from getting an invalid lifetime. Most native method implementations (that is, `#[no_mangle] extern "system" fn`s) must now make the `JNIEnv` parameter `mut`. See the example on the crate documentation. ([#392](https://github.com/jni-rs/jni-rs/issues/392))
50- `JByteBuffer`, `JClass`, `JNIEnv`, `JObject`, `JString`, and `JThrowable` no longer have the `Clone` or `Copy` traits. This improves safety by preventing object references from being used after the JVM deletes them. Most functions that take one of these types as a parameter (except `extern fn`s that are directly called by the JVM) should now borrow it instead, e.g. `&JObject` instead of `JObject`. ([#392](https://github.com/jni-rs/jni-rs/issues/392))
51- `AutoLocal` is now generic in the type of object reference (`JString`, etc). ([#392](https://github.com/jni-rs/jni-rs/issues/392))
52- The closure passed to `JNIEnv::with_local_frame` must now take a `&mut JNIEnv` parameter, which has a different lifetime. This improves safety by preventing local references from escaping the closure, which would cause a use-after-free bug. `Executor::with_attached` and `Executor::with_attached_capacity` have been similarly changed. ([#392](https://github.com/jni-rs/jni-rs/issues/392))
53- The closure passed to `JNIEnv::with_local_frame` can now return a generic `Result<T, E>` so long as the error implements `From<jni::errors::Error>` ([#399](https://github.com/jni-rs/jni-rs/issues/399))
54- `JNIEnv::with_local_frame` now returns the same type that the given closure returns ([#399](https://github.com/jni-rs/jni-rs/issues/399))
55- `JNIEnv::with_local_frame` no longer supports returning a local reference directly to the calling scope (see `with_local_frame_returning_local`) ([#399](https://github.com/jni-rs/jni-rs/issues/399))
56- `Executor::with_attached` and `Executor::with_attached_capacity` have been changed in the same way as `JNIEnv::with_local_frame` (they are thin wrappers) ([#399](https://github.com/jni-rs/jni-rs/issues/399))
57- `Desc`, `JNIEnv::pop_local_frame`, and `TypeArray` are now `unsafe`. ([#392](https://github.com/jni-rs/jni-rs/issues/392))
58- The `Desc` trait now has an associated type `Output`. Many implementations now return `AutoLocal`, so if you call `Desc::lookup` yourself and then call `as_raw` on the returned object, make sure the `AutoLocal` isn't dropped too soon (see the `Desc::lookup` documentation for examples). ([#392](https://github.com/jni-rs/jni-rs/issues/392))
59- The `Desc<JClass>` trait is no longer implemented for `JObject` or `&JObject`. The previous implementation that called `.get_object_class()` was surprising and a simpler cast would make it easy to mistakenly pass instances where a class is required. ([#118](https://github.com/jni-rs/jni-rs/issues/118))
60- Named lifetimes in the documentation have more descriptive names (like `'local` instead of `'a`). The new naming convention is explained in the `JNIEnv` documentation. ([#392](https://github.com/jni-rs/jni-rs/issues/392))
61- Object reference types (`JObject`, `JClass`, `AutoLocal`, `GlobalRef`, etc) now implement `AsRef<JObject>` and `Deref<Target = JObject>`. Typed wrappers like `JClass` also implement `Into<JObject>`, but `GlobalRef` does not. ([#392](https://github.com/jni-rs/jni-rs/issues/392))
62- Most `JList` and `JMap` methods now require a `&mut JNIEnv` parameter. `JListIter` and `JMapIter` no longer implement `Iterator`, and instead have a `next` method that requires a `&mut JNIEnv` parameter (use `while let` loops instead of `for`). ([#392](https://github.com/jni-rs/jni-rs/issues/392))
63- `JValue` has been changed in several ways: ([#392](https://github.com/jni-rs/jni-rs/issues/392))
64    - It is now a generic type named `JValueGen`. `JValue` is now a type alias for `JValueGen<&JObject>`, that is, it borrows an object reference. `JValueOwned` is a type alias for `JValueGen<JObject>`, that is, it owns an object reference.
65    - `JValueOwned` does not have the `Copy` trait.
66    - The `to_jni` method is now named `as_jni`, and it borrows the `JValueGen` instead of taking ownership.
67    - `JObject` can no longer be converted directly to `JValue`, which was commonly done when calling Java methods or constructors. Instead of `obj.into()`, use `(&obj).into()`.
68- All `JNIEnv` array APIs now work in terms of `JPrimitiveArray` and `JObjectArray` (reference wrappers with a lifetime) instead of `sys` types like `jarray` and `jbyteArray` ([#400](https://github.com/jni-rs/jni-rs/pull/400))
69- `AutoArray` and `AutoPrimitiveArray` have been renamed `AutoElements` and `AutoElementsCritical` to show their connection and differentiate from new `JPrimitiveArray` API ([#400](https://github.com/jni-rs/jni-rs/pull/400))
70- `get_primitive_array_critical` is now `unsafe` and has been renamed to `get_array_elements_critical` (consistent with the rename of `AutoPrimitiveArray`) with more detailed safety documentation ([#400](https://github.com/jni-rs/jni-rs/pull/400))
71- `get_array_elements` is now also `unsafe` (for many of the same reasons as `get_array_elements_critical`) and has detailed safety documentation ([#400](https://github.com/jni-rs/jni-rs/pull/400))
72- `AutoArray/AutoArrayCritical::size()` has been replaced with `.len()` which can't fail and returns a `usize` ([#400](https://github.com/jni-rs/jni-rs/pull/400))
73- The `TypeArray` trait is now a private / sealed trait, that is considered to be an implementation detail for the `AutoArray` API.
74- `JvmError` has several more variants and is now `non_exhaustive`. ([#414](https://github.com/jni-rs/jni-rs/pull/414))
75- `InitArgsBuilder::option` raises an error on Windows if the string is too long. The limit is currently 1048576 bytes. ([#414](https://github.com/jni-rs/jni-rs/pull/414))
76
77### Fixed
78- Trying to use an object reference after it has been deleted now causes a compile error instead of undefined behavior. As a result, it is now safe to use `AutoLocal`, `JNIEnv::delete_local_ref`, and `JNIEnv::with_local_frame`. (Most of the limitations added in #392, listed above, were needed to make this work.) ([#381](https://github.com/jni-rs/jni-rs/issues/381), [#392](https://github.com/jni-rs/jni-rs/issues/392))
79- Class lookups via the `Desc` trait now return `AutoLocal`s, which prevents them from leaking. ([#109](https://github.com/jni-rs/jni-rs/issues/109), [#392](https://github.com/jni-rs/jni-rs/issues/392))
80- `InitArgsBuilder::option` properly encodes non-ASCII characters on Windows. ([#414](https://github.com/jni-rs/jni-rs/pull/414))
81
82### Removed
83- `get_string_utf_chars` and `release_string_utf_chars` from `JNIEnv` (See `JavaStr::into_raw()` and `JavaStr::from_raw()` instead) ([#372](https://github.com/jni-rs/jni-rs/pull/372))
84- All `JNIEnv::get_<type>_array_elements()` methods have been removed as redundant since they would all be equivalent to `get_array_elements()` with the introduction of `JPrimitiveArray` ([#400](https://github.com/jni-rs/jni-rs/pull/400))
85
86## [0.20.0] — 2022-10-17
87
88### Added
89- `Default` trait implemented for `JObject`, `JString`, `JClass`, and `JByteBuffer` ([#199](https://github.com/jni-rs/jni-rs/issues/199))
90- `Debug` trait implemented for `JavaVM`, `GlobalRef`, `GlobalRefGuard`, `JStaticMethodID` and `ReleaseMode` ([#345](https://github.com/jni-rs/jni-rs/pull/345))
91- `ReturnType` for specifying object return types without a String allocation. ([#329](https://github.com/jni-rs/jni-rs/issues/329))
92
93### Changed
94- The `release_string_utf_chars` function has been marked as unsafe. ([#334](https://github.com/jni-rs/jni-rs/pull/334))
95- Mark `JNIEnv::new_direct_byte_buffer` as `unsafe` ([#320](https://github.com/jni-rs/jni-rs/pull/320))
96- `JNIEnv::new_direct_byte_buffer` now takes a raw pointer and size instead of a slice ([#351](https://github.com/jni-rs/jni-rs/pull/351) and [#364](https://github.com/jni-rs/jni-rs/pull/364))
97- `JNIEnv::direct_buffer_address` returns a raw pointer instead of a slice ([#364](https://github.com/jni-rs/jni-rs/pull/364))
98- The lifetime of `AutoArray` is no longer tied to the lifetime of a particular `JNIEnv` reference. ([#302](https://github.com/jni-rs/jni-rs/issues/302))
99- Relaxed lifetime restrictions on `JNIEnv::new_local_ref`. Now it can be used to create a local
100  reference from a global reference. ([#301](https://github.com/jni-rs/jni-rs/issues/301) / [#319](https://github.com/jni-rs/jni-rs/pull/319))
101- `JMethodID` and `JStaticMethodID` implement `Send` + `Sync` and no longer has a lifetime parameter, making method
102  IDs cacheable (with a documented 'Safety' note about ensuring they remain valid). ([#346](https://github.com/jni-rs/jni-rs/pull/346))
103- `JFieldID` and `JStaticFieldID` implement `Send` + `Sync` and no longer has a lifetime parameter, making field
104  IDs cacheable (with a documented 'Safety' note about ensuring they remain valid). ([#346](https://github.com/jni-rs/jni-rs/pull/365))
105- The `call_*_method_unchecked` functions now take `jni:sys::jvalue` arguments to avoid allocating
106  a `Vec` on each call to map + collect `JValue`s as `sys:jvalue`s ([#329](https://github.com/jni-rs/jni-rs/issues/329))
107- The `From` trait implementations converting `jni_sys` types like `jobject` to `JObject` have been replaced
108  with `unsafe` `::from_raw` functions and corresponding `::into_raw` methods. Existing `::into_inner` APIs were
109  renamed `::into_raw` for symmetry. ([#197](https://github.com/jni-rs/jni-rs/issues/197))
110- The APIs `JNIEnv::set_rust_field`, `JNIEnv::get_rust_field` and `JNIEnv::take_rust_field` have been marked as `unsafe` ([#219](https://github.com/jni-rs/jni-rs/issues/219))
111
112## [0.19.0] — 2021-01-24
113
114### Added
115- `AutoArray` and generic `get_array_elements()`, along with `get_<type>_array_elements` helpers. (#287)
116- `size()` method to `AutoArray` and `AutoPrimitiveArray`. (#278 / #287)
117- `discard()` method to `AutoArray` and `AutoPrimitiveArray`. (#275 / #287)
118
119### Changed
120- Removed AutoPrimitiveArray::commit(). (#290)
121- `AutoByte/PrimitiveArray.commit()` now returns `Result`. (#275)
122- Removed methods get/release/commit_byte/primitive_array_{elements|critical}. (#281)
123- Renamed methods get_auto_byte/long/primitive_array_{elements|critical} to
124	get_byte/long/primitive_array_{elements|critical}. (#281)
125
126## [0.18.0] — 2020-09-23
127
128### Added
129- `JNIEnv#define_unnamed_class` function that allows loading a class without
130  specifying its name. The name is inferred from the class data. (#246)
131- `SetStatic<type>Field`. (#248)
132- `TryFrom<JValue>` for types inside JValue variants (#264).
133- Implemented Copy for JNIEnv (#255).
134- `repr(transparent)` attribute to JavaVM struct (#259)
135
136### Changed
137- Switch from `error-chain` to `thiserror`, making all errors `Send`. Also, support all JNI errors
138  in the `jni_error_code_to_result` function and add more information to the `InvalidArgList`
139  error. ([#242](https://github.com/jni-rs/jni-rs/pull/242))
140
141## [0.17.0] — 2020-06-30
142
143### Added
144- Get/ReleaseByteArrayElements, and Get/ReleasePrimitiveArrayCritical. (#237)
145
146## [0.16.0] — 2020-02-28
147
148### Fixed
149- Java VM instantiation with some MacOS configurations. (#220, #229, #230).
150
151## [0.15.0] — 2020-02-28
152
153### Added
154- Ability to pass object wrappers that are convertible to `JObject` as arguments to the majority
155 of JNIEnv methods without explicit conversion. (#213)
156- `JNIEnv#is_same_object` implementation. (#213)
157- `JNIEnv#register_native_methods`. (#214)
158- Conversion from `Into<JObject>` to `JValue::Object`.
159
160### Fixed
161- Passing `null` as class loader to `define_class` method now allowed according
162  to the JNI specification. (#225)
163
164## [0.14.0] — 2019-10-31
165
166### Changed
167- Relaxed some lifetime restrictions in JNIEnv to support the case when
168  method, field ids; and global references to classes
169  have a different (larger) lifetime than JNIEnv. (#209)
170
171## [0.13.1] — 2019-08-22
172
173### Changed
174- Various documentation improvements.
175
176## [0.13.0] — 2019-07-05
177
1780.13 brings major improvements in thread management, allowing to attach the native threads
179permanently and safely; `Executor` for extra convenience and safety; and other
180improvements and fixes.
181
182:warning: If your code attaches native threads — make sure to check the updated documentation
183of [JavaVM](https://docs.rs/jni/0.13.0/jni/struct.JavaVM.html) to learn about the new features!
184
185### Added
186- `JavaVM::attach_current_thread_permanently` method, which attaches the current
187  thread and detaches it when the thread finishes. Daemon threads attached
188  with `JavaVM::attach_current_thread_as_daemon` also automatically detach themselves
189  when finished. The number of currently attached threads may be acquired using
190  `JavaVM::threads_attached` method. (#179, #180)
191- `Executor` — a simple thread attachment manager which helps to safely
192  execute a closure in attached thread context and to automatically free
193  created local references at closure exit. (#186)
194
195### Changed
196- The default JNI API version in `InitArgsBuilder` from V1 to V8. (#178)
197- Extended the lifetimes of `AutoLocal` to make it more flexible. (#190)
198- Default exception type from checked `java.lang.Exception` to unchecked `java.lang.RuntimeException`.
199  It is used implicitly when `JNIEnv#throw` is invoked with exception message:
200  `env.throw("Exception message")`; however, for efficiency reasons, it is recommended
201  to specify the exception type explicitly *and* use `throw_new`:
202  `env.throw_new(exception_type, "Exception message")`. (#194)
203
204### Fixed
205- Native threads attached with `JavaVM::attach_current_thread_as_daemon` now automatically detach
206  themselves on exit, preventing Java Thread leaks. (#179)
207- Local reference leaks in `JList`, `JMap` and `JMapIter`. (#190, #191)
208
209## [0.12.3]
210
211### Added
212- `From<jboolean>` implementation for `JValue` (#173)
213- `Debug` trait for InitArgsBuilder. (#175)
214- `InitArgsBuilder#options` returning the collected JVM options. (#177)
215
216## [0.12.2]
217
218### Changed
219- Updated documentation of GetXArrayRegion methods (#169)
220- Improved ABI compatibility on various platforms (#170)
221
222## [0.12.1]
223
224This release does not bring code changes.
225
226### Changed
227- Updated project documentation.
228
229## [0.12.0]
230
231### Changed
232- `JString`, `JMap` and `JavaStr` and their respective iterators now require an extra lifetime so
233  that they can now work with `&'b JNIEnv<'a>`, where `'a: 'b`.
234
235## [0.11.0]
236
237### Highlights
238This release brings various improvements and fixes, outlined below. The most notable changes are:
239- `null` is no longer represented as an `Err` with error kind `NullPtr` if it is a value of some
240  nullable Java reference (not an indication of an error). Related issues: #136, #148, #163.
241- `unsafe` methods, providing a low-level API similar to JNI, has been marked safe and renamed
242  to have `_unchecked` suffix. Such methods can be used to implement caching of class references
243  and method IDs to improve performance in loops and frequently called Java callbacks.
244  If you have such, check out [the docs][unchecked-docs] and [one of early usages][cache-exonum]
245  of this feature.
246
247[unchecked-docs]: https://docs.rs/jni/0.11.0/jni/struct.JNIEnv.html
248[cache-exonum]: https://github.com/exonum/exonum-java-binding/blob/affa85c026c1870b502725b291822c00f199745d/exonum-java-binding/core/rust/src/utils/jni_cache.rs#L40
249
250### Added
251- Invocation API support on Windows and AppVeyor CI (#149)
252
253### Changed
254- `push_local_frame`, `delete_global_ref` and `release_string_utf_chars`
255no longer check for exceptions as they are
256[safe](https://docs.oracle.com/javase/10/docs/specs/jni/design.html#exception-handling)
257to call if there is a pending exception (#124):
258  - `push_local_frame` will now work in case of pending exceptions — as
259  the spec requires; and fail in case of allocation errors
260  - `delete_global_ref` and `release_string_utf_chars` won't print incorrect
261  log messages
262
263- Rename some macros to better express their intent (see #123):
264  - Rename `jni_call` to `jni_non_null_call` as it checks the return value
265  to be non-null.
266  - Rename `jni_non_null_call` (which may return nulls) to `jni_non_void_call`.
267
268- A lot of public methods of `JNIEnv` have been marked as safe, all unsafe code
269  has been isolated inside internal macros. Methods with `_unsafe` suffixes have
270  been renamed and now have `_unchecked` suffixes (#140)
271
272- `from_str` method of the `JavaType` has been replaced by the `FromStr`
273  implementation
274
275- Implemented Sync for GlobalRef (#102).
276
277- Improvements in macro usage for JNI methods calls (#136):
278  - `call_static_method_unchecked` and `get_static_field_unchecked` methods are
279  allowed to return NULL object
280  - Added checking for pending exception to the `call_static_method_unchecked`
281  method (eliminated WARNING messages in log)
282
283- Further improvements in macro usage for JNI method calls (#150):
284  - The new_global_ref() and new_local_ref() functions are allowed to work with NULL objects according to specification.
285  - Fixed the family of functions new_direct_byte_buffer(), get_direct_buffer_address() and get_direct_buffer_capacity()
286   by adding checking for null and error codes.
287  - Increased tests coverage for JNIEnv functions.
288
289- Implemented Clone for JNIEnv (#147).
290
291- The get_superclass(), get_field_unchecked() and get_object_array_element() are allowed to return NULL object according
292 to the specification (#163).
293
294### Fixed
295- The issue with early detaching of a thread by nested AttachGuard. (#139)
296
297## [0.10.2]
298
299### Added
300- `JavaVM#get_java_vm_pointer` to retrieve a JavaVM pointer (#98)
301- This changelog and other project documents (#106)
302
303### Changed
304- The project is moved to an organization (#104)
305- Updated versions of dependencies (#105)
306- Improved project documents (#107)
307
308### Fixed
309- Crate type of a shared library with native methods
310  must be `cdylib` (#100)
311
312## [0.10.1]
313- No changes has been made to the Changelog until this release.
314
315[Unreleased]: https://github.com/jni-rs/jni-rs/compare/v0.21.1...HEAD
316[0.21.1]: https://github.com/jni-rs/jni-rs/compare/v0.21.0...v0.21.1
317[0.21.0]: https://github.com/jni-rs/jni-rs/compare/v0.20.0...v0.21.0
318[0.20.0]: https://github.com/jni-rs/jni-rs/compare/v0.19.0...v0.20.0
319[0.19.0]: https://github.com/jni-rs/jni-rs/compare/v0.18.0...v0.19.0
320[0.18.0]: https://github.com/jni-rs/jni-rs/compare/v0.17.0...v0.18.0
321[0.17.0]: https://github.com/jni-rs/jni-rs/compare/v0.16.0...v0.17.0
322[0.16.0]: https://github.com/jni-rs/jni-rs/compare/v0.15.0...v0.16.0
323[0.15.0]: https://github.com/jni-rs/jni-rs/compare/v0.14.0...v0.15.0
324[0.14.0]: https://github.com/jni-rs/jni-rs/compare/v0.13.1...v0.14.0
325[0.13.1]: https://github.com/jni-rs/jni-rs/compare/v0.13.0...v0.13.1
326[0.13.0]: https://github.com/jni-rs/jni-rs/compare/v0.12.3...v0.13.0
327[0.12.3]: https://github.com/jni-rs/jni-rs/compare/v0.12.2...v0.12.3
328[0.12.2]: https://github.com/jni-rs/jni-rs/compare/v0.12.1...v0.12.2
329[0.12.1]: https://github.com/jni-rs/jni-rs/compare/v0.12.0...v0.12.1
330[0.12.0]: https://github.com/jni-rs/jni-rs/compare/v0.11.0...v0.12.0
331[0.11.0]: https://github.com/jni-rs/jni-rs/compare/v0.10.2...v0.11.0
332[0.10.2]: https://github.com/jni-rs/jni-rs/compare/v0.10.1...v0.10.2
333[0.10.1]: https://github.com/jni-rs/jni-rs/compare/v0.1...v0.10.1
334