1If you want to import files from the OpenJDK into `libcore/`, you are reading 2the right documentation. 3 4The general idea is to get a change from OpenJDK into libcore in AOSP by 5`git merge` from an OpenJDK branch. However, each file in `ojluni/` can come 6from a different OpenJDK version. `expected_upstream` is a staging branch 7storing the OpenJDK version of each file. Thus, we can use `git merge` when 8we update an `ojluni/` file from a new upstream version, and the command should 9automatically merge the file if no merge conflict. 10 11# Directory Layout 12in the `aosp/expected_upstream` branch. 131. `ojluni/` 14 * It has the same layout as the ojluni/ files in `aosp/master` 152. `EXPECTED_UPSTREAM` file 16 * The table has 3 columns, i.e. 17 1. Destination path in `ojluni/` 18 2. Expected upstream version / an upstream git tag 19 3. Upstream source path 20 * The file format is like .csv file using a `,` separator 213. `tools/expected_upstream/` 22 * Contains the tools 23 24# Understanding your change 25## Changes that shouldn't happen in the `aosp/expected_upstream` branch 26In general, if you want to change an `ojluni/` file by a text editor / IDE 27manually, you should make the change on `aosp/master`. 28 291. Changes to non-OpenJDK files 30 * Those files are usually under the `luni/` folder, you can make the change 31 directly on `aosp/master` 322. Adding / updating a patch to an existing `ojluni/` file 33 * You can make the change directly on `aosp/master`. Please follow this 34 [patch style guideline](https://goto.google.com/libcore-openjdk8-verify). 353. Cherry-picking a commit from upstream 36 * You should first try to update an `ojluni/` file to a particular upstream 37 version. If you can't but still want to cherry-pick a upstream fix, you 38 should do so on the `aosp/master` branch. 394. Changes to non-OpenJDK files in `ojluni/` 40 * Files, e.g. Android.bp, don't come from the upstream. You can make the 41 change directly on `aosp/master`. 42 43## Changes that should be made via the `aosp/expected_upstream` branch 44 451. Add or upgrade a file from the upstream OpenJDK 46 * You are reading the right document! This documentation tells you how to 47 import the file from the upstream. Later, you can merge the file and 48 `expected_upstream` into `aosp/master` branch. 492. Remove an `ojluni/` file that originally came from the OpenJDK 50 * Please remove the file on both `aosp/master` and `aosp/expected_upstream` 51 branches. Don't forget to remove the entry in the `EXPECTED_UPSTREAM` too. 523. Revert the merge commit on `aosp/master` from `expected_upstream` 53 * If you don't plan to re-land your change on `aosp/master`, you should 54 probably revert the change `aosp/expected_upstream` as well. 55 * If you plan to re-land your change, your re-landing commit won't be 56 a merge commit, because `git` doesn't allow you to merge the same commit 57 twice into the same branch. You have 2 options 58 1. Revert your change on `expected_upsteam` too and start over again 59 when you reland your change 60 2. Just accept that the re-landing commit won't be a merge commit. 61 62## Life of a typical change 63 64Commit graph of a typical change 65```text 66----11.0.13-ga---------------- openjdk/jdk11u 67 \ 68 A 69 \ 70------------B-----C------------ expected_upstream 71 \ 72--------------------D---E------ master 73``` 74 75Typically, you will need 5 CLs 76* Commit `A` imports the file and moves the file in the `ojluni/` folder 77* Commit `B` merges the file into the expected_upstream with other `ojluni` 78 files 79 * Commit `A` and `B` are created by the `ojluni_refresh_files` script 80* Commit `C` edits the entry in the `EXPECTED_UPSTREAM` file 81* Commit `D` is a merge commit created by `git merge` 82* Commit `E` adds Android patches 83 * Includes other changes to non-OpenJDK files, e.g. `Android.bp`, 84 `api/current.txt`. 85 86### Why can't have a single commit to replace the commits `A`, `B` and `C`? 87* Preserve the upstream history. We can later `git blame` with the upstream 88 history. 89 90# Tools 91 92## Prerequisite 93* python3 94* pip3 95* A remote `aosp` is setup in your local git repository 96 97## List of the scripts 98### tools/expected_upstream/install_tools.sh 99* Installs the dependency libraries 100* Installs the other tools into your current shell process 101 102### ojluni_modify_expectation 103* Command line tool that can help modify the EXPECTED_UPSTREAM file 104 105### ojluni_refresh_files 106* Reads the EXPECTED_UPSTREAM file and updates the files contents in ojluni/ 107accordingly 108 109## Workflow in command lines 110### Setup 1111. Switch to the expected_upstream branch 112```shell 113git branch <local_branch> aosp/expected_upstream 114git checkout <local_branch> 115``` 116 1172. Install tools 118```shell 119source ./tools/expected_upstream/install_tools.sh 120``` 121## Upgrade a java class to a higher OpenJDK version 122For example, upgrade `java.lang.String` to 11.0.13-ga version: 123 124```shell 125ojluni_modify_expectation modify java.lang.String jdk11u/jdk-11.0.13-ga 126ojluni_refresh_files 127``` 128 129or if `java.lang.String` is missing in EXPECTED_UPSTREAM: 130```shell 131ojluni_modify_expectation add jdk11u/jdk-11.0.13-ga java.lang.String 132ojluni_refresh_files 133``` 1342 commits should be created to update the `ojluni/src/main/java/java/lang/String.java`. 135You can verify and view the diff by the following command 136 137```shell 138git diff aosp/expected_upstream -- ojluni/src/main/java/java/lang/String.java 139``` 140 141You can then upload your change to AOSP gerrit. 142```shell 143repo upload --cbr -t . # -t sets a topic to the CLs in the gerrit 144``` 145 146Remember to commit your EXPECTED_UPSTREAM file change into a new commit 147```shell 148git commit -- EXPECTED_UPSTREAM 149``` 150 151Then upload your change to AOSP gerrit. 152```shell 153repo upload --cbr . 154``` 155 156Then you can switch back to your local `master` branch to apply the changes 157```shell 158git checkout <local_master_branch> 159git merge local_expected_upstream 160# Resolve any merge conflict 161git commit --amend # Amend the commit message and add the bug number you are working on 162repo upload . 163``` 164 165### Add a java test from the upstream 166 167The process is similar to the above commands, but needs to run 168`ojluni_modify_expectation` with an `add` subcommand. 169 170For example, add a test for `String.isEmpty()` method: 171```shell 172ojluni_modify_expectation add jdk8u/jdk8u121-b13 java.lang.String.IsEmpty 173``` 174Note: `java.lang.String.IsEmpty` is a test class in the upstream repository. 175 176# Submit your change in [AOSP gerrit](http://r.android.com/) 177```text 178----11.0.13-ga---------------- openjdk/jdk11u 179 \ 180 A 181 \ 182------------B-----C------------ expected_upstream 183 \ 184--------------------D---E------ master 185``` 186Here are the order of events / votes required to submit your CL on gerrit as of 187Nov 2021. 1881. `Presubmit-Verified +2` on all 5 CLs 189 * Due to [b/204973624](http://b/204973624), you may `Bypass-Presubmit +1` 190 on commit `A` and `B` if the presubmit fails. 1912. `Code-review +2` on all 5 CLs from an Android Core Library team member 1923. If needed, `API-review +1` on commit `E` from an Android API council member 1934. Click the submit button / `Autosubmit +1` on commit `B`, `C` and `E` 194 * Never submit commit `A` individually without submitting `B` together. 195 * Otherwise, gerrit will create another merge commit from `A` without 196 submitting `B`. 197 * Due a Gerrit bug, you can't submit the commit `C` before submitting `B` 198 first manually, even though `B` is the direct parent of `C`. So just 199 submit `B` yourself manually. 200 * If you can't submit the CL due a permission issue, ask an Android Core 201 Library member to submit. 202 203# Known bugs 204* `repo upload` may not succeed because gerrit returns error. 205 1. Just try to run `repo upload` again! 206 * The initial upload takes a long time because it tries to sync with the 207 remote AOSP gerrit server. The second upload is much faster because 208 the `git` objects have been uploaded. 209 2. `repo upload` returns TimeOutException, but the CL has been uploaded. 210 Just find your CL in http://r.android.com/. See http://b/202848945 211 3. Try to upload the merge commits 1 by 1 212 ```shell 213 git rev-parse HEAD # a sha is printed and you will need it later 214 git reset HEAD~1 # reset to a earlier commit 215 repo upload --cbr . # try to upload it again 216 git reset <the sha printed above> 217 ``` 218* After `ojluni_modify_expectation add` and `ojluni_refresh_files`, a `git commit -a` 219 would include more files than just EXPECTED_UPSTREAM, because `git`, e.g. `git status`, 220 isn't aware of changes in the working tree / in the file system. This can lead to 221 an error when checking out the branch that is based on master. 222 1. Do a `git checkout --hard <initial commit before the add>` 223 2. Rerun the `ojluni_modify_expectation add` and `ojluni_refresh_files` 224 3. `git stash && git stash pop` 225 4. Commit the updated EXPECTED_UPSTREAM and proceed 226 227# Report bugs 228* Report bugs if the git repository is corrupt! 229 * Sometimes, you can recover the repository by running `git reset aosp/expected_upstream` 230