Web3j android branch harmonisation with master

The Android version of Web3j is maintained on a separate branch to the Java 8+ supported main Web3j project.

The simple reason being that Web3j was originally written in Java 8 to target Java devs. Android came along after the fact following a request from just some guy

Unfortunately this means that each Web3j release needs to be backported to Android, which is a maintenance nightmare, and inevitably means that the Android releases are always behind the main JVM releases.

Really what we need to do is eliminate the need to backport, and have a single project branch that can be used to cut releases for both platforms without comprimising features for users - i.e. we don’t want to force Java users to use old syntax, nor restrict Androiid users to more recent versions of the platform only.

The most logical solution IMHO is to rewrite the library in Kotlin, (please let me know if you think otherwise) but I’d be interested to hear any other opinions people may have, as a rewrite would be a time consuming undertaking.

Thoughts from @sergeys:

If Android is wanted to be one of the supported platforms in web3j (along with vanilla Java) I think you should reconsider the way it’s treated.

Probably, the most important thing for us, at Opera, is that we can get a new Android-compatible version of web3j as soon as the new Java version is released.

If you ask me, the simplest way to achieve this is to make the project code compatible with both Android and Java. But what would it mean?

1. The code is written with language features supported both in Java and Android virtual machine (VM). It might be achieved by using a subset of Java language (e.g. without streams not supported on older Android versions) or a new language, such as Kotlin.
2. Platform-dependent things (such as, e.g. BouncyCastle library) are moved outside of the common code (into platform-dependent modules). Note that this has to be done regardless of whether or not Kotlin is used as the primary language.

I strongly discourage you from a complete rewrite in Kotlin as it would take a huge amount of time, will cause regressions and is simply not worth it (what are the benefits? Same code as in Android? But you still need to fix #2 from the list above, so the code will diverge).

My suggestion is to:

1. Use Java as it is now but limit its features only to those supported both on Android and Java VMs.
*2. Introduce platform-dependent modules which might contain code relevant to the target platforms (Java or Android). *
3. Make sure that any code change integrated to the project is compatible with Android/Java.
4. Introduce a compatibility module to avoid common developer errors.

A glimpse of what this would require can be seen in my previous PR.

Agreed, we need to isolate the parts we want to keep as cross-platform (i.e using a reduced jdk version) and those that are platform-specific. Because this would mean moving a bunch of things about and potentially renaming modules it gives an opportunity to tidy a lot of things up. Specifically, we want to have more targeted in the artefact names

Something like:

The ‘base’ modules

web3j-eth-rpc (mostly from core)

all targeting the reduced jvm version (ideally without using https://github.com/stefan-zobel/streamsupport)

And then have specific implementations that can support newer/language specific features

e.g web3j-eth-rx and web3j-eth-kt when time permits.

I’m supportive of any initiative that will support greater adoption of web3j-android. The approaches suggested by @sergeys and @antony make sense to me. Especially as Android users typically are very focused with respect to the specific components of Web3j that they wish to use. Whereas Java devs tend not to mind as they don’t usually have the same deployment platform constraints as mobile developers.

I do believe that a Kotlin code base would simplify long term maintainability of the project as we wouldn’t need to carve out certain modules for specific JVMs, but I appreciate that that’s a much larger undertaking.

That being said, I would be interested to know if if we did follow the outlined cross-platform/platform-specific approach, could there not be some fairly straight-forward conversions to Kotlin for some of the more lightweights components? For instance the RLP module should be pretty straight forward to convert as a starting point.

Sounds good to me.

That being said, I would be interested to know if if we did follow the outlined cross-platform/platform-specific approach, could there not be some fairly straight-forward conversions to Kotlin for some of the more lightweights components?
Sure, why not? Kotlin and Java are interoperable. Simple components can be converted from Java to Kotlin automatically.

Can you give some advice to those already using web3j-android today?
I always wondered why no releases for android took place after 4.2.0 and if we should try to make a build ourselves.
Reading through this thread, I get the understanding that it’s far from trivial to create something like a 4.5.x-android build.

This however leaves me with the question if there’s anything we (as wallet devs) can do about it in the meantime. In our case e.g. there’s 2 changes (this and this) added after 4.2.0 which we need pretty urgently.
Would you advise us to try backporting those to 4.2.0 and making a build ourselves?
Or is it an option to make up-to-date builds of individual modules?

You’ll find the ENS update is in the android branch: https://github.com/web3j/web3j/blob/release/4.2.1-android/core/src/main/java/org/web3j/ens/Contracts.java