Saturday, April 30, 2022

IDEA / HandBrake / WSL Port Conflict

Recently I upgraded HandBrake to the latest version, however, it stopped working. The root cause is TCP port conflict. As usual, I ran net stop winnat && net start winnat and it worked. But, that broke WSL network.

I didn't want to reset the winnat every time I started Windows with a broken WSL. Finally, I found the root cause: Hyper-V reserves huge amount of TCP ports after Windows is up. The fix is to tell Hyper-V to avoid those commonly used TCP ports.

The following command can show you the excluded TCP port ranges.

> netsh int ipv4 show excludedportrange protocol=tcp

Protocol tcp Port Exclusion Ranges

Start Port    End Port
----------    --------
        80          80
      1000        1010
      1020        1030

As you can see, huge amount of TCP ports are reserved by Hyper-V. So, let's tell Hyper-V not to be that greedy by executing the following command.

> netsh int ipv4 set dynamic tcp start=49152 num=16384

That command tells Windows to allow dynamic TCP ports from 49152 so that Hyper-V is only able to reserve TCP ports starting from 49152. The following command can verify the setting is correct.

> netsh int ipv4 show dynamic protocol=tcp

Protocol tcp Dynamic Port Range
Start Port      : 49152
Number of Ports : 16384

Once the new dynamic TCP port range is set, just reboot your machine and everything goes back to normal. IDEA can start smoothly, WSL network is always on, HandBrake works all the time.

Tuesday, January 11, 2022

dlopen failed: cannot locate symbol "__aarch64_ldadd4_relax"

In Android development, it's rare to meet the following error.

dlopen failed: cannot locate symbol "__aarch64_ldadd4_relax"

I searched the whole internet for a solution, but couldn't get a practical one. Actually, the root cause is simple: The Android NDK is too old.

The solution in my case is:

  1. Upgrade CMake to the latest version.
  2. Upgrade Android NDK to the latest version.

Wednesday, November 3, 2021

Monday, October 25, 2021

Javet for Android is Released

Javet is Java + V8 (JAVa + V + EighT). It is an awesome way of embedding Node.js and V8 in Java.

It's been more than half a year for the Javet users to wait for the Android support. Now, Javet has officially supported Android.

The API and coding experience are identical to the ones on Linux, Mac OS and Windows.

Friday, October 22, 2021

Javet for Android is on the Way

Javet is Java + V8 (JAVa + V + EighT). It is an awesome way of embedding Node.js and V8 in Java.

It's been a long while for many Javet users to wait for the Android support. Now, it is coming true as the first Android build is being tested. If you are interested, please join us at discord.

Friday, September 10, 2021

MacBook Air mid-2012 from Lion to Catalina

I had been asked by potential Javet users for Mac OS release for many moths before the first Mac OS release was published. I have to admit I have no plan to purchase Mac OS devices in the new future for financial reason.

Luckily, I have a MacBook Air mid-2012 resting in the dust. I revived it and would like to upgrade it to the latest Mac OS.

The problem was I had to upgrade it to Lion, then to El Capitan, Mojave, eventually to Catalina which is the last version supported by MacBook Air mid-2012.

It took ~8 hours to get there. Then, I installed xcode and related tools. Luckily, it met the lowest requirement for building V8 v9.2.

Obviously, MacBook Air mid-2012 is tooooo slow in building modern applications. It took ~4 hours to build V8, and another ~4 hours to build Node.js. The result was good as Javet for Mac OS x86_64 was built successfully.

However, MacBook Air mid-2012 will soon been retired by a new release of V8. When that day comes, I will no longer release Mac OS x86_64 version unless I get enough donation for me to purchase a new device.

Migrate from J2V8 to Javet

How to migrate from J2V8 to Javet is a frequently asked question, especially when people are evaluating Javet. I created Javet in Jan, 2021 for various reasons (What is the Motivation?, History with J2V8). After the first release v0.7.0 was published, I started migrating from J2V8 to Javet. It was quite smooth, though it took a week.

Why Migrate from J2V8 to Javet?

  • Its Linux, Mac OS and Windows releases have been abandoned for years.

  • Its type hierarchy is inconsistent because primitive types are out of the hierarchy so that tedious if-else sentences have to be repeated all over the code base.

  • Its function registration API is kind of verbose.

  • Segfaults take place so frequently and don't get maintainers' attention for years.

  • Its locking mechanism heavily increases mental pressure in the code base.

  • Its V8 runtime is not multi-threaded friendly unless application adds a synchronous layer on top of it.

Migration Guides

V8 ⟶ V8Runtime

  • V8 in J2V8 is V8Runtime in Javet.

  • V8 in J2V8 carries 2 roles: 1 as the V8 runtime and 1 as the global object (globalThis or global). In Javet, V8Runtime no longer inherits from V8Value so that it literally represents the V8 runtime. V8Runtime.getGlobalObject() is dedicated to the global object.

  • V8Runtime has much richer API than V8 has. E.g. compileV8Module(), lowMemoryNotification(), terminateExecution().

Primitive Types

  • Primitive types in Javet inherit from V8ValuePrimitiveV8ValueV8Data.

  • The Javet type hierarchy is consistent so that V8Value in all supported API can represent all V8 types. This is hard in J2V8 because Object has to be used to represent all types, however, by using Object the type check during compilation doesn't work at all and that is a rich source of runtime bugs or even segfaults.

registerJavaMethod() ⟶ @V8Function

  • It is quite painful to register many functions in J2V8. Javet makes that a declarative one instead of the imperative one. Just decorate the target function with @V8Function, then call V8ValueObject.bind(javaObject) to bind that Java object, it's done.

  • In addition, Javet provides @V8Property which allows registering getters and setters in the same manner. That feature has never been delivered by J2V8.

  • Javet also allows unbinding the registration. Just call V8ValueObject.unbind(javaObject).

Please refer to V8 Function for more details.


  • Javet introduced Implicit Mode which allows applications to eliminate V8Locker from the code base and still be able to share the same V8Runtime among multiple threads, because Javet does the synchronization automatically. That frees applications developers from the tedious acquire() and release() calls, and gets the rid of the runtime exceptions caused by multiple threads.

  • Javet also has Explicit Mode for performance sensitive scenarios.

Please refer to Know the Lock for more details.

Type Conversion

  • Javet has built-in JavetObjectConverter which covers the majority cases on type conversion so that the arguments of Javet API can be of any type and the converter just does the conversion transparently. That frees application developers from writing tedious type conversion code everywhere.

  • Javet also provides JavetProxyConverter which allows injecting arbitrary Java objects in V8 and polyfilling Java interfaces with JavaScript functions or objects. Especially the polyfilling feature implies hotfixing business logic without restarting the JVM.

Please refer to Object Converter for more details.

Node.js and V8

  • Javet provides both Node.js mode and V8 mode for various usages. Each mode stays at a dedicated classloader so that both modes don't cross each other, and are completely isolated. If the application only uses one mode, it doesn't need to pay extra amount of memory for the other mode because the other mode is not loaded at all. Of course, both modes can be unloaded as well without shutting down the JVM.

  • In Node.js mode, all node modules can be directly used including the native modules. Please refer to Modularization for more detail.

  • In V8 mode, it is much more secure than the Node.js mode is, but lacks of some basic ES API, e.g. setTimeout(). Project Javenode is the one that aims at simulating Node.js with Java in Javet V8 mode.

Please refer to Javet Design for more details.

ES6 Module

  • Javet supports import { *** } from '***.js' and exposes module resolve event for applications to specify where to locate the modules.

Please refer to Modularization for more detail.


In case this migration guide couldn't cover all your use cases, please contact the maintainer at discord. Wish you a successful migration!

IDEA / HandBrake / WSL Port Conflict

Recently I upgraded HandBrake to the latest version, however, it stopped working. The root cause is TCP port conflict. As usual, I ran net s...