Skip to content

Commit c342209

Browse files
authored
Merge pull request #52 from ev3dev-lang-java/docs/maintainer_manual_markdown
docs: add the Maintainer's Manual translated to Markdown
2 parents 9abe1a1 + 6638412 commit c342209

13 files changed

+653
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## Adding new major OpenJDK version
2+
3+
Upstream produces new OpenJDK releases in a half-year cadence.
4+
The tip/master build (masqueraded as latest version) on Jenkins should
5+
keep up with this, as master is always master.
6+
7+
To add a new released version, add an appropriate section in the
8+
config.sh shell script. It's probably best to start by copying an older
9+
release configuration and modifying it to match the new release configuration.
10+
11+
There is hopefully only one catch: the Host/Boot JDK provided should be
12+
of the same or previous release (e.g. for building JDK13, it should be
13+
JDK13 or JDK12). Usually AdoptOpenJDK builds are used for x86 builders
14+
and our builds are used for ARM builders.
15+
16+
For setting up Jenkins builds, please see
17+
[Integration with AdoptOpenJDK Jenkins](AdoptOpenJDK_Jenkins.md).

docs/AdoptOpenJDK_Jenkins.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
## Integration with AdoptOpenJDK Jenkins
2+
3+
To automate the build process, the project uses the AdoptOpenJDK
4+
Jenkins CI hosted at [ci.adoptopenjdk.net][adopt1] for its builds.
5+
The [ev3dev tab][adopt2] is dedicated to jobs of this project.
6+
7+
The integration is based on Jenkins Pipelines. In the root of the
8+
repository, there is a Jenkinsfile describing the build steps & nodes
9+
where it can run. It handles the following actions:
10+
1. Docker container image building
11+
- This is a prerequisite of the OpenJDK build.
12+
Docker pipelines integration is used to build the container.
13+
2. OpenJDK build
14+
- This builds the Java binary archives. However, Jenkinsfile bypasses
15+
the autorun.sh script and runs the build phases directly.
16+
By doing that, it is possible to have a separate Jenkins pipeline
17+
stages for our phases.
18+
3. Artifact upload
19+
- This uploads the binary archives to the Jenkins master, where they
20+
are made available for download by the Internet.
21+
4. Cleanup
22+
- As the build workspace & container images take quite a lot of space,
23+
it is necessary to remove them after the build finishes
24+
(whether successfully or not).
25+
26+
The Jenkinsfile expects to be given some parameters.
27+
At the time of writing, the following parameters exist:
28+
* `JDKVM_VALUE` - sets the JVM JIT to be used. See `JDKVM` for config.sh.
29+
* `JDKVER_VALUE` - sets the JDK version to be built. See `JDKVER` for config.sh.
30+
* `JDKPLATFORM_VALUE` - sets the target platform. See `JDKPLATFORM` for config.sh.
31+
* `DOCKER_ARCH` - target arch. It should match the platform. Currently only `armel`.
32+
* `DEBIAN` - Debian release - can be set to `stretch` or `buster`.
33+
* `BUILD_TYPE` - either `cross` or `native` - sets the build model (x86>ARM vs ARM>ARM)
34+
* `DISABLED` - with this enabled, the build will always do nothing and
35+
it will always succeed. This is useful for cleanup of old jobs.
36+
37+
There parameters can be forced to specific values for individual jobs
38+
by using single-choice "choice parameter".
39+
40+
Currently all configured builds reside in the [`eljbuild`][eljbuild] folder.
41+
Except for JDK9 & JDK10, they all represent the ARMv8->ARM compilation
42+
path for the given Debian & JDK versions.
43+
44+
To create a new Jenkins job, simply create a copy of an existing job and
45+
then customize the job parameters.
46+
47+
[adopt1]: https://ci.adoptopenjdk.net/
48+
[adopt2]: https://ci.adoptopenjdk.net/view/ev3dev/
49+
[eljbuild]: https://ci.adoptopenjdk.net/view/ev3dev/job/eljbuild/

docs/Building.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
## Building OpenJDK
2+
3+
### Intro
4+
5+
The goal of this project is to provide a small enough Java runtime that
6+
would run on ev3dev on EV3. Currently OpenJDK is used for this.
7+
The reason is simple - it contains an Oracle-developed and then
8+
opensourced fast ARM32 JIT from JDK9 onwards. The second reason is that
9+
leJOS EV3 had used a similar JDK (Embedded JDK 7/8), but it was a
10+
proprietary offering prepared and not later updated by Oracle.
11+
12+
### Build system
13+
14+
![native vs cross builders](images/host_machine_archs.png)
15+
16+
To build the OpenJDK binaries in an environment suitable for
17+
cross-compilation for EV3, the repository is using a couple of Docker
18+
containers. They have two variants: `native` (ARM host -> ARM target) and
19+
`cross` (x86 host -> ARM target). The native builders have an advantage
20+
in that the JDK can be partially tested right on the build machine.
21+
22+
![build system layers](images/build_system_layers.png)
23+
24+
The layers of the build environment are shown on the picture above.
25+
The lower docker container/image contains the target OS (Debian/ev3dev)
26+
with its libraries and compilers. This is done to ensure that the API
27+
provided by the system and its libraries are compatible between the build
28+
and target machines.
29+
30+
On top of that, there resides a set of shell scripts which control the build.
31+
Their task is to download JDK and source-level dependencies and to build
32+
the JDK binaries with its build system.
33+
34+
These two containers have to be built before the build of OpenJDK itself.
35+
Afterwards, the scripts in the upper container take over the rest of
36+
the build process.
37+
38+
It should be notes that as the builds run in a container, it is
39+
necessary to mount a directory from the host to the container as
40+
a build workspace. This makes it possible to access the built binaries.
41+
42+
### Build scripts
43+
44+
Let's return back to the scripts. There are six build scripts in total:
45+
* `autobuild.sh` - This is the entrypoint for the build.
46+
It calls the last four scripts in succession
47+
if autobuild is enabled. Otherwise it just exits
48+
into shell.
49+
* `config.sh`
50+
- This script is `source`'d from the last four scripts.
51+
- It takes in the JDK version and other parameters from environment
52+
variables passed to the container and in turn it exports different
53+
environment variables to be used by other build scripts
54+
(like the JDK source URL).
55+
* `prepare.sh` - This script contains the *Prepare* phase.
56+
1. It downloads and unpacks the Host JDK (needed for OpenJDK build)
57+
to a directory in the build workspace. This is then used to build
58+
the Java classes of the resulting JDK.
59+
2. It also downloads JTreg, which is used when building included
60+
test cases (not currently run on Jenkins; but they can be run manually).
61+
* `fetch.sh` - This scripts contains the *Fetch* phase.
62+
1. It determines the SCM parameters (commit hash, real version).
63+
From them, it generates a metadata file used to identify the build.
64+
Usually the latest GA release is picked.
65+
2. It then has to download the OpenJDK source code.
66+
3. It applies the patches stored in this repository.
67+
4. It clones one extra repository - the AdoptOpenJDK
68+
[openjdk-build][bld] repository used for the CA certificates.
69+
* `build.sh` - This script is doing the *Build* phase.
70+
1. It configures the JDK build using the `configure` script.
71+
2. It runs the JDK build using `make`.
72+
- If the build is running on native (ARM) hardware, it also runs a
73+
bootcycle build, which uses the newly built JDK to build itself
74+
once more. This provides a basic level of testing.
75+
* `zip.sh` - This script finishes the build with the *Archiving* stage.
76+
1. It generates the JRI (Java Runtime Image) for the EV3,
77+
which is basically a reduced Java runtime.
78+
1. It then packs that and remaining build outputs (such as JMOD
79+
packages and the full JDK) into a tarball which is then uploaded
80+
as a build artifact.
81+
82+
[bld]: https://github.com/adoptopenjdk/openjdk-build
83+
84+
![build stages](images/build_process.png)
85+
86+
### Build parameters
87+
88+
The build scripts accept a predefined set of environment variables
89+
describing the build. The parameters need to be passed in via Docker
90+
environment variables; see [Manual build](#manual-build) for an example.
91+
92+
* `JDKVER` - sets the JDK version to build.
93+
- One of `11`, `12`, `13`, `tip`, `loom`.
94+
Numeric versions will usually build the latest tagged
95+
General-Availability releases; `tip` will build the latest commit.
96+
- *Note.* When a new JDK version is branched out for stabilization,
97+
then the latest non-GA tag must used, as there are no GA tags yet.
98+
* `JDKVM` - sets the JVM JIT to use. One of:
99+
- `zero`: portable non-assembler JIT/interpreter.
100+
It's quite slow, but it should always work.
101+
- `client`: fast ARM assembler-assisted JIT.
102+
- `minimal`: similar to `client`, but should be a bit smaller.
103+
Unfortunately, this configuration does not build
104+
successfully (the linking process will fail).
105+
* `JDKPLATFORM` - sets the platform for the build scripts. Only `ev3` is allowed.
106+
* `JDKDEBUG` - sets the JVM debug level. Optional. One of (from JDK source):
107+
- `release`: no debug information, all optimizations, no asserts.
108+
- `optimized`: no debug information, all optim., no asserts, HS tgt is 'optimized'.
109+
- `fastdebug`: debug information (-g), all optimizations, all asserts
110+
- `slowdebug`: debug information (-g), no optimizations, all asserts
111+
* `AUTOBUILD` - when set to `1` or `yes`, it runs the autorun.sh script
112+
directly instead of the shell.
113+
114+
### Build outputs
115+
116+
The output of the build process are three different archives:
117+
* `jmods-ev3.tar.gz` - contains Java JMODs.
118+
These are pieces of the JDK that can be assembled into a proper and
119+
useful JRE/JDK/JRI; see [here][jmod]. They are intended to be
120+
processed with the jlink tool provided with host-native Java JDK.
121+
* `jri-ev3.tar.gz` - EV3 JRI.
122+
This is a smaller version of traditional JRE. It is intended to be
123+
used as a Java runtime for the brick. It contains only a few Java
124+
modules in order to reduce its size.
125+
* `jdk-ev3.tar.gz` - Full EV3 JDK. This directory comes from the JDK
126+
build process; however, it is likely also built internally using jlink.
127+
This could be useful for someone who wants to do full Java
128+
development on the brick.
129+
130+
[jmod]: https://www.developer.com/java/data/how-modules-are-packaged-in-java-9.html
131+
132+
### Manual build
133+
You can run the build OpenJDK on your own computer too. This script should do that:
134+
135+
```sh
136+
# define parameters
137+
TARGET_WORKSPACE="$(pwd)/build" # 10 GB of free space should be sufficient
138+
TARGET_DEBIAN_VERSION="stretch" # stretch or buster
139+
TARGET_OPENJDK_VERSION="11" # 11, 12, 13, tip, loom are on Jenkins
140+
141+
# clone repository
142+
git clone https://github.com/ev3dev-lang-java/openjdk-ev3.git
143+
cd openjdk-ev3
144+
145+
# prepare working directory
146+
mkdir -p "$TARGET_WORKSPACE"
147+
chmod -R 777 "$TARGET_WORKSPACE" # docker may not share UID with the current user
148+
149+
# build base system container
150+
docker build --build-arg DEBIAN_RELEASE="$TARGET_DEBIAN_VERSION" \
151+
--build-arg ARCH="armel" \
152+
--tag "ev3dev-lang-java:jdk-cross-$TARGET_DEBIAN_VERSION" \
153+
--file ./system/Dockerfile.cross \
154+
./system
155+
156+
# on top of that, create a build scripts container
157+
docker build --build-arg commit="$(git rev-parse HEAD)" \
158+
--build-arg extra="Manual build #1 by $(whoami)" \
159+
--build-arg DEBIAN_RELEASE="$TARGET_DEBIAN_VERSION" \
160+
--build-arg BUILD_TYPE="cross" \
161+
--tag "ev3dev-lang-java:jdk-cross-build" \
162+
./scripts
163+
164+
# now run the build
165+
docker run --rm \
166+
--interactive \
167+
--tty \
168+
--volume "$TARGET_WORKSPACE:/build" \
169+
--env JDKVER="$TARGET_OPENJDK_VERSION" \
170+
--env JDKVM="client" \
171+
--env JDKPLATFORM="ev3" \
172+
--env JDKDEBUG="release" \
173+
--env AUTOBUILD="1" \
174+
ev3dev-lang-java:jdk-cross-build
175+
176+
# finally, make workspace accessible for all users (i.e. current one too)
177+
chmod -R 777 "$TARGET_WORKSPACE"
178+
# and list the output directory (now it should contain three *-ev3.tar.gz files)
179+
ls "$TARGET_WORKSPACE"
180+
```
181+
182+
See [issue #34][manual_build].
183+
184+
[manual_build]: https://github.com/ev3dev-lang-java/openjdk-ev3/issues/34

docs/Contents.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# OpenJDK-EV3 Maintainer's Manual
2+
3+
This manual goes through an overview of this project.
4+
It is a version of the [old manual](https://docs.google.com/document/d/1rsBDU68_ETXm9b_Lb4b6oPVBbNwT9f4xEua2w3-Pm6A)
5+
converted to pure Markdown.
6+
7+
![overview of the release process](images/release_process.png)
8+
9+
Contents:
10+
* [Building OpenJDK](Building.md)
11+
* [Included out-of-tree patches](Included_patches.md)
12+
* [Debugging issues with OpenJDK](Debugging.md)
13+
* [Adding new major OpenJDK version](Adding_new_major_OpenJDK_version.md)
14+
* [Packaging, signing and uploading for ev3dev](Packaging_signing_uploading.md)
15+
* [Integration with AdoptOpenJDK Jenkins](AdoptOpenJDK_Jenkins.md)
16+
* [Ideas about testing the builds](Testing_ideas.md)

docs/Debugging.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## Debugging issues with OpenJDK
2+
3+
Sometimes it is necessry to investigate a crash in native code.
4+
If the problem is not in an external library, it is likely that something
5+
went wrong inside the JVM. In that case, the following steps might help
6+
you with diagnosing the problem:
7+
8+
9+
* Try to reproduce it on a more powerful machine (like with ARMv7 CPU).
10+
If it reproduces, continue testing on this machine.
11+
Good machines for this include newer Raspberry Pis and Odroid SBCs.
12+
* Try to reproduce it using QEMU (e.g. in the Docker packaging container).
13+
If it reproduces, continue there.
14+
* Somehow get the debug symbols for the Java runtime. The
15+
`jri-11-ev3-dbgsym` package from the repositories should suffice.
16+
Alternatively, run a manual build to get a `fastdebug` or `slowdebug`
17+
build (value of `JDKDEBUG` environment variable) and try to reproduce
18+
the issue there.
19+
- Optionally, you can also build the hsdis native disassembler for
20+
diagnosing JIT compiler issues. However, I have not tried this.
21+
It should give the ability to print JIT-generated ASM code;
22+
however, it is also possible to disassemble it directly from GDB.
23+
* Try to diagnose the issue with GDB - either by investigating the
24+
core dump generated by the crash (to enable them, run
25+
`ulimit -c unlimited`) or by triggering it in GDB. Another way is to
26+
start the GDB only once the crash happens. See [here][jvm_gdb],
27+
for more details, however I think the inner gdb command should be `gdb -p %p`.
28+
* Try to discover the cause of the bug by walking through
29+
the stack trace and the source code.
30+
31+
[jvm_gdb]: https://neugens.wordpress.com/2015/02/26/debugging-the-jdk-with-gdb/

docs/Included_patches.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
## Included out-of-tree patches
2+
3+
In order to fix some issues in upstream OpenJDK, this repository
4+
contains some out-of-tree patches.
5+
6+
### What we include
7+
8+
Note: JTreg included tests = tests bundled with the OpenJDK source tree.
9+
10+
#### OpenJDK 9
11+
12+
*is not present anymore*
13+
14+
#### OpenJDK 10
15+
16+
*is not present anymore*
17+
18+
#### OpenJDK 11
19+
* `jdk11.patch` - fixes runtime errors & adds cflags optimizations.
20+
* `jdk11_nosflt.patch` - removes the need for the external softfloat-3e library.
21+
* `jdk11_lib.patch` - adds Debian JNI library path to the build.
22+
* `jdk11_new.patch` - fixes bugs found on JDK12 by JTreg incl. test on ARMv7.
23+
* `jdk11_bkpt.patch` - disables ARM-specific breakpoint instruction on VM errors.
24+
* `jdk11_cds.patch` - fixes crash (JTreg incl. test) caused by incorrect CDS data alignment.
25+
* `jdk11_jfr.patch` - fixes crash (JTreg incl. test) in the Java Flight Recorder file writer.
26+
27+
#### OpenJDK 12
28+
* `jdk12_nosflt.patch` - removes the need for the external softfloat-3e library.
29+
* `jdk12_new.patch` - fixes bugs found on JDK12 by JTreg incl. test on ARMv7.
30+
* `jdk12_bkpt.patch` - disables ARM-specific breakpoint instruction on VM errors.
31+
* `jdk12_cds.patch` - fixes crash (JTreg incl. test) caused by incorrect CDS data alignment.
32+
* `jdk12_jfr.patch` - fixes crash (JTreg incl. test) in Java Flight Recorder file writer.
33+
34+
#### OpenJDK 13
35+
* `jdk13_nosflt.patch` - removes the need for the external softfloat-3e library.
36+
* `jdk13_new.patch` - fixes bugs found on JDK12 by JTreg incl. test on ARMv7.
37+
* `jdk13_bkpt.patch` - disables ARM-specific breakpoint instruction on errors.
38+
* `jdk13_cds.patch` - fixes crash (JTreg incl. test) caused by incorrect CDS data alignment.
39+
* `jdk13_jfr.patch` - fixes crash (JTreg incl. test) in Java Flight Recorder file writer.
40+
41+
#### OpenJDK 14
42+
* `jdk14_nosflt.patch` - removes the need for the external softfloat-3e library.
43+
* `jdk14_new.patch` - fixes bugs found on JDK12 by JTreg incl. test on ARMv7.
44+
* `jdk14_bkpt.patch` - disables ARM-specific breakpoint instruction on errors.
45+
* `jdk14_cds.patch` - fixes crash (JTreg incl. test) caused by incorrect CDS data alignment.
46+
* `jdk14_jfr.patch` - fixes crash (JTreg incl. test) in Java Flight Recorder file writer.
47+
48+
49+
### Patch rebasing
50+
As the development continues in the OpenJDK upstream, is is necessary
51+
to rebase the patches from time to time (or properly upstream them).
52+
This can be done this way:
53+
54+
1. Clone the JDK Git repositories on the correct tags:
55+
```sh
56+
git clone --branch jdk-11.0.4-ga --depth 1 https://github.com/openjdk/jdk11u.git && cd jdk11u
57+
```
58+
2. Apply the current patches one by one as individual commits, fixing the conflicts that arise.
59+
```sh
60+
patch -p1 -i <patch1>
61+
rm <...>.orig
62+
git add <...>
63+
git commit -m “patch1”
64+
```
65+
3. Print the commit log to get the hashes of the created commits.
66+
```sh
67+
git log # or git hist, but you have to add an alias
68+
```
69+
4. Re-export the patches by running the following command between individual commits:
70+
```sh
71+
git diff <previoushash> <thishash> > <patch1>
72+
```
73+
74+
### Upstreaming
75+
To upstream a patch (see also [OpenJDK guide][jdkguide]):
76+
1. Sign the Oracle Contributor Agreement and send it to Oracle.
77+
2. Create an issue in the JDK Bug System. (might be optional)
78+
3. Work on the patch.
79+
4. Send it to an appropriate mailing list and iterate on enhancing it until it's OK.
80+
81+
[jdkguide]: https://openjdk.java.net/contribute/

0 commit comments

Comments
 (0)