# Technical Documentation: google/j2objc

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/google/j2objc)

### Overview (`README.md`)

# J2ObjC: Java to Objective-C Translator and Runtime #

**Project site:** <https://j2objc.org><br>
**J2ObjC blog:** <https://j2objc.blogspot.com><br>
**Questions and discussion:** <https://groups.google.com/group/j2objc-discuss>

### What J2ObjC Is ###
J2ObjC is an open-source command-line tool from Google that translates
Java source code to Objective-C for the iOS (iPhone/iPad) platform. This tool
enables Java source to be part of an iOS application's build, as no editing
of the generated files is necessary. The goal is to write an app's non-UI
code (such as application logic and data models) in Java, which is then
shared by web apps (using [GWT](http://www.gwtproject.org/)), Android apps,
and iOS apps.

J2ObjC supports most Java language and runtime features required by
client-side application developers, including exceptions, inner and
anonymous classes, generic types, threads and reflection. JUnit test
translation and execution is also supported.

J2ObjC is currently beta quality. Several Google projects rely on it, but
when new projects first start working with it, they usually find new bugs
to be fixed. If you run into issues with your project, please report them!

### What J2ObjC isn't ###
J2ObjC does not provide any sort of platform-independent UI toolkit, nor are
there any plans to do so in the future. We believe that iOS UI code needs to
be written in Objective-C, Objective-C++ or Swift using Apple's iOS SDK (Android
UIs using Android's API, web app UIs using GWT, etc.).

J2ObjC cannot convert Android binary applications. Developers must have source
code for their Android app, which they either own or are licensed to use.

## Requirements ##

* JDK 21
* Mac workstation or laptop
* OS X 15.6.1 or higher
* Xcode 16.3 or higher

## License ##

This library is distributed under the Apache 2.0 license found in the
[LICENSE](https://github.com/google/j2objc/blob/master/LICENSE) file.
The protocol buffers library is distributed under the same BSD license as
Google's protocol buffers. See its
[README](https://github.com/protocolbuffers/protobuf/blob/master/README.md) and
[LICENSE](https://github.com/protocolbuffers/protobuf/blob/master/LICENSE).

## Running on GNU/Linux ##

To build and run on GNU/Linux, install [the Darling project](http://www.darlinghq.org/), then following [its Compile and Run a Program example](https://wiki.darlinghq.org/what_to_try#compile_and_run_a_program). Please note that j2objc is only supported on iOS/macOS.

## Artifact Signatures ##

This project publishes some artifacts through Maven Central with a `groupId` of `com.google.j2objc`.
These artifacts are currently signed with [the following PGP/GPG key]
(https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xC3259D20DAEC4ACE6D57CC83340B090F727518D8):

```
---------
pub   ed25519 2025-08-13 [SC] [expires: 2028-08-12]
      C3259D20DAEC4ACE6D57CC83340B090F727518D8
uid           [ultimate] Thomas Ball <tball@google.com>
sub   cv25519 2025-08-13 [E] [expires: 2028-08-12]
```

Older artifacts are signed with the following PGP/GPG keys:

```
pub   rsa2048 2023-01-10 [SC] [expires: 2025-01-09]
      EB1B3DE71713C9EC2E87CC26EE92349AD86DE446
uid           [ unknown] Thomas Ball <tball@google.com>
sub   rsa2048 2023-01-10 [E] [expires: 2025-01-09]
```

```
pub   rsa2048 2015-09-25 [SC]
      B801E2F8EF035068EC1139CC29579F18FA8FD93B
uid           [ unknown] Tom Ball <tball724@gmail.com>
sub   rsa2048 2015-09-25 [E]
```

---

### Overview (`tree_shaker/README.md`)

J2ObjC Tree Shaker

About:
The tree shaker project is an experimental tool in the J2ObjC family that lets 
users detect any unused code in their Java program. The purpose of the tool is 
to provide the translator with a list of unused elements in the code that it 
can remove to reduce the size of the translated project.

Usage:
The tree shaker can be used in two ways:

1. Manual Analysis: Using the tree shaker by itself on a package of source 
files, it will report a set of classes and methods that it detected as unused.
2. Dead Code Elimination in Translator: The tree-shaker-report output file, 
generated by the tree shaker, can be used as an input to the translator, using 
its Dead Code Elimination functionality (see the docs for translator). This 
will automatically remove the unused code reported by the tree shaker from the 
final translated source code.

Running Tree Shaker:
The tree shaker command takes in a few flags, as seen in the help message:

```
Usage: tree_shaker <options> <source files>
where possible options include:
  -sourcepath <path>           Specify where to find input source files.
  -classpath <path>            Specify where to find user class files.
  --tree-shaker-roots          Specify a file that lists the public root classes and methods.
  -s, --sourcefilelist <file>  Specify a file that lists the source files to be analyzed.
  -encoding <encoding>         Specify character encoding used by source files
  -Xbootclasspath:<path>       Boot path used to compile the input sources. (not the tool itself)
  -version                     Version information
  -Werror                      Treats all warning as errors.
  -h, --help                   Print this message.
```

All elements in the input source files that can be reached from the public 
roots will be kept, and the others marked as unused. The input file formatting 
for classes is the full packageName.className for the class, one class per line:

```
# These are the root classes for this library:
foo.bar.Mumble
itsy.bitsy.Spider

# Inner-classes work, too:
twisty.little.Passage.Direction
```

When indicating a class as a public root, the tree shaker will take all public 
methods inside that class and add them to the public root set, for convenience.
To add specific methods to the public root set, add their enclosing class's 
packageName.className, followed by a colon, and all of the root set methods 
inside that class on the following lines, one on each line, preceded by 4 
spaces. For example, this tells `tree_shaker` to only mark the `main` method as
used, which allows other methods to potentially be reported as dead:

```
my.little.Pony:
    main(java.lang.String[])
```

Ending Note:
The tree shaker tool is an experimental project, used at the user's own risk. 
The manual analysis use case is completely safe, and is the recommended way to 
analyze source code for unused elements while the tree shaker is still in 
testing. More adventurous users are encouraged to experiment with dead code 
elimination, find and/or fix bugs, and submit pull requests.

---

### Overview (`jre_emul/junit_tests/README.md`)

# JRE JUnit Tests

This is a simple iOS app that redirects System.out and System.err to a
scrollable panel, then runs the [JUnit](http://junit.org) tests for the
J2ObjC's JRE library as a background task. Test output is also saved as
a file on the iOS device, which can be uploaded from Xcode's Organizer
window.

### App Icons ###

The project's app icons for this app were created using
[GIMP for Mac OS X](http://www.gimp.org/downloads/), then converted into iOS
icons using the [Macappicon app icon generator](http://makeappicon.com/). To
update the icons to the lastest iOS requirements, drag the junit-tests-logo.png
file to MakeAppIcon's toaster, enter your email when it's created the icon set
and it will be mailed to your account. Unzip the icon set and copy
ios/AppIcon.appiconset to j2objc/jre_emul/junit_tests/Images.xcassets/.

### Reuse and Improve ###

Feel free to clone this app and change it to run your app's JUnit tests.
We're also very interested in any improvements that would help make testing
easier.

---

### Overview (`jre_emul/android/platform/external/okhttp/okio/README.md`)

Okio
====

Okio is a new library that complements `java.io` and `java.nio` to make it much
easier to access, store, and process your data.

ByteStrings and Buffers
-----------------------

Okio is built around two types that pack a lot of capability into a
straightforward API:

 * [**ByteString**][3] is an immutable sequence of bytes. For character data, `String`
   is fundamental. `ByteString` is String's long-lost brother, making it easy to
   treat binary data as a value. This class is ergonomic: it knows how to encode
   and decode itself as hex, base64, and UTF-8.

 * [**Buffer**][4] is a mutable sequence of bytes. Like `ArrayList`, you don't need
   to size your buffer in advance. You read and write buffers as a queue: write
   data to the end and read it from the front. There's no obligation to manage
   positions, limits, or capacities.

Internally, `ByteString` and `Buffer` do some clever things to save CPU and
memory. If you encode a UTF-8 string as a `ByteString`, it caches a reference to
that string so that if you decode it later, there's no work to do.

`Buffer` is implemented as a linked list of segments. When you move data from
one buffer to another, it _reassigns ownership_ of the segments rather than
copying the data across. This approach is particularly helpful for multithreaded
programs: a thread that talks to the network can exchange data with a worker
thread without any copying or ceremony.

Sources and Sinks
-----------------

An elegant part of the `java.io` design is how streams can be layered for
transformations like encryption and compression. Okio includes its own stream
types called [`Source`][5] and [`Sink`][6] that work like `InputStream` and
`OutputStream`, but with some key differences:

 * **Timeouts.** The streams provide access to the timeouts of the underlying
   I/O mechanism. Unlike the `java.io` socket streams, both `read()` and
   `write()` calls honor timeouts.

 * **Easy to implement.** `Source` declares three methods: `read()`, `close()`,
   and `timeout()`. There are no hazards like `available()` or single-byte reads
   that cause correctness and performance surprises.

 * **Easy to use.** Although _implementations_ of `Source` and `Sink` have only
   three methods to write, _callers_ are given a rich API with the
   [`BufferedSource`][7] and [`BufferedSink`][8] interfaces. These interfaces give you
   everything you need in one place.

 * **No artificial distinction between byte streams and char streams.** It's all
   data. Read and write it as bytes, UTF-8 strings, big-endian 32-bit integers,
   little-endian shorts; whatever you want. No more `InputStreamReader`!

 * **Easy to test.** The `Buffer` class implements both `BufferedSource` and
   `BufferedSink` so your test code is simple and clear.

Sources and sinks interoperate with `InputStream` and `OutputStream`. You can
view any `Source` as an `InputStream`, and you can view any `InputStream` as a
`Source`. Similarly for `Sink` and `OutputStream`.

Dependable
----------

Okio started as a component of [OkHttp][1], the capable HTTP+SPDY client
included in Android. It's well-exercised and ready to solve new problems.


Example: a PNG decoder
----------------------

Decoding the chunks of a PNG file demonstrates Okio in practice.

```java
private static final ByteString PNG_HEADER = ByteString.decodeHex("89504e470d0a1a0a");

public void decodePng(InputStream in) throws IOException {
  BufferedSource pngSource = Okio.buffer(Okio.source(in));

  ByteString header = pngSource.readByteString(PNG_HEADER.size());
  if (!header.equals(PNG_HEADER)) {
    throw new IOException("Not a PNG.");
  }

  while (true) {
    Buffer chunk = new Buffer();

    // Each chunk is a length, type, data, and CRC offset.
    int length = pngSource.readInt();
    String type = pngSource.readUtf8(4);
    pngSource.readFully(chunk, length);
    int crc = pngSource.readInt();

    decodeChunk(type, chunk);
    if (type.equals("IEND")) break;
  }

  pngSource.close();
}

private void decodeChunk(String type, Buffer chunk) {
  if (type.equals("IHDR")) {
    int width = chunk.readInt();
    int height = chunk.readInt();
    System.out.printf("%08x: %s %d x %d%n", chunk.size(), type, width, height);
  } else {
    System.out.printf("%08x: %s%n", chunk.size(), type);
  }
}
```

Download
--------

Download [the latest JAR][2] or grab via Maven:
```xml
<dependency>
    <groupId>com.squareup.okio</groupId>
    <artifactId>okio</artifactId>
    <version>1.6.0</version>
</dependency>
```
or Gradle:
```groovy
compile 'com.squareup.okio:okio:1.6.0'
```

Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap].


 [1]: https://github.com/square/okhttp
 [2]: https://search.maven.org/remote_content?g=com.squareup.okio&a=okio&v=LATEST
 [3]: http://square.github.io/okio/okio/ByteString.html
 [4]: http://square.github.io/okio/okio/Buffer.html
 [5]: http://square.github.io/okio/okio/Source.html
 [6]: http://square.github.io/okio/okio/Sink.html
 [7]: http://square.github.io/okio/okio/BufferedSource.html
 [8]: http://square.github.io/okio/okio/BufferedSink.html
 [snap]: https://oss.sonatype.org/content/repositories/snapshots/

---

--- METRICS ---
- Files Extracted: 4
- Estimated Token Budget: ~3247 tokens
- Canonical Reference: https://codewiki.google/github.com/google/j2objc
