1# Jni-rs Contribution Guide
2
3Jni-rs is open to any contributions, whether
4it is a feedback on existing features, a request for a new one, a bug report
5or a pull request. This document describes how to work with this project:
6
7* how to [build](#how-to-build) it
8* how to [test](#tests) it
9* the [code style guidelines](#the-code-style)
10* how to [submit an issue](#submitting-issues)
11* how to [submit a PR](#submitting-pull-requests).
12
13## How to Build
14
15### System Dependencies
16
17You need to install the following dependencies:
18
19* [JDK 1.8+](http://jdk.java.net/10/).
20* [Rust (latest stable)](https://www.rust-lang.org/).
21
22### Building
23
24To build `jni-rs`, simply run
25
26```$sh
27cargo build
28```
29
30inside project root directory. You can also build the library in release mode by
31adding `--release` flag.
32
33## Tests
34
35### Categories of Tests
36
37* Unit tests are typically placed at the bottom of their module file.
38  E.g. [unit tests of signature module](src/wrapper/signature.rs). Tests are wrapped
39  in private module with `test` attribute:
40
41  ```rust
42  #[cfg(test)]
43  mod test {
44    use super::*;
45
46    #[test]
47    fn first_test() { /* ... */ }
48
49    // More tests...
50  }
51  ```
52
53* Integration tests are in [tests directory](tests). They use the same pattern as
54  unit tests, but split into several files instead of private modules.
55  Integration tests use `jni-rs` as every other Rust application — by importing
56  library using `extern crate` keyword.
57
58  ```rust
59    extern crate jni;
60    use jni::*;
61  ```
62
63  Integration tests typically require running a JVM, so you should add
64  `#![cfg(feature = "invocation")]` at the top of the file. You can use helper
65  methods from [util module](tests/util/mod.rs) to run JVM.
66
67  Keep in mind, that only one JVM can be run per process. Therefore, tests that
68  need to launch it with different parameters have to be placed in different
69  source files. `Cargo` runs tests from different modules in parallel.
70
71* Benchmarks are in [benches](benches) directory. As integration tests, they
72  require launching a JVM from native.
73
74* Doc tests are rarely used, but they allow to efficiently test some functionality
75  by providing an example of its usage. Consult
76  [Rust documentation](https://doc.rust-lang.org/beta/rustdoc/documentation-tests.html)
77  for more info about writing these tests.
78
79### Running Tests
80
81#### Setup Environment
82
83As some tests need to launch a JVM, add a directory with JVM library that you want
84to use to `LD_LIBRARY_PATH` on Linux/Mac or `PATH` environment variable on Windows.
85On Linux/Mac, you can use the following script for this purpose:
86
87```$sh
88source test_profile
89```
90
91#### Run Tests
92
93To run all tests, execute the following command:
94
95```$sh
96cargo test --features=invocation
97```
98
99This command will run all tests, including unit, integration and documentation
100tests.
101
102#### Run Benchmarks
103
104To run all benchmarks, execute the following command (nightly Rust required):
105
106```$sh
107cargo +nightly bench --features=invocation
108```
109
110They might help you to see the performance differences between
111two [API flavours][checked-unchecked]: checked and unchecked, and
112pick the right one for your application.
113
114[checked-unchecked]: https://docs.rs/jni/0.21.1/jni/struct.JNIEnv.html#checked-and-unchecked-methods
115
116## The Code Style
117
118Rust code follows the [Rust style guide](https://github.com/rust-lang-nursery/fmt-rfcs/blob/master/guide/guide.md).
119[`rustfmt`](https://github.com/rust-lang-nursery/rustfmt) enforces the code style.
120
121After installation, you can run it with
122
123```$sh
124cargo fmt --all -- --check
125```
126
127Every public entry of the API must be thoroughly documented and covered with tests if it is possible.
128You can use [JNI specification](https://docs.oracle.com/javase/10/docs/specs/jni/index.html) as
129a reference for how to write detailed documentation.
130
131Do not forget to update project guides and tutorials along with documentation.
132
133To open local documentation of the project, you can use the following command:
134
135```$sh
136cargo doc --open
137```
138
139## Submitting Issues
140
141Use Github Issues to submit an issue, whether it is a question, some feedback, a bug or a feature request: <https://github.com/jni-rs/jni-rs/issues/new>
142
143## Submitting Pull Requests
144
145Before starting to work on a PR, please submit an issue describing the intended changes.
146Chances are — we are already working on something similar. If not — we can then offer some
147help with the requirements, design, implementation or documentation.
148
149It’s fine to open a PR as soon as you need any feedback — ask any questions in the description.
150
151## License
152
153Licensed under either of
154
155* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
156  <http://www.apache.org/licenses/LICENSE-2.0>)
157* MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
158  at your option.
159
160### Contributor License Agreement
161
162Unless you explicitly state otherwise, any contribution intentionally
163submitted for inclusion is the work by you, as defined in the
164Apache-2.0 license, shall be dual licensed as above, without any
165additional terms or conditions.
166