LiquidPlayer / LiquidCore

Node.js virtual machine for Android and iOS
MIT License
1.01k stars 127 forks source link

Can't install LiquidCore in V8-only mode #170

Closed Arvoreniad closed 4 years ago

Arvoreniad commented 4 years ago

I'm trying to set up LiquidCore according to the guidelines here so that I can execute Javascript using a JSContext, without the need to install the whole Node.js feature set.

I'm not certain from the documentation whether installing the JSC to V8 translation layer (described in the "JavaScriptCore API" section of that wiki page) should be necessary for JSContext to work. However, if I follow the setup instructions under the "Installation" heading on the wiki page, using apply from: new File(rootProject.projectDir, 'node_modules/liquidcore/include.V8.gradle') to load LiquidCore in my build.gradle file, I am not able to import org.liquidplayer.javascript.JSContext into any Java file in my project - the module doesn't appear to exist.

So instead, I tried the method listed under the "JavaScriptCore API" section, now using apply from: new File(rootProject.projectDir, 'node_modules/liquidcore/addon.gradle') in my build.gradle file. I created a CMakeLists.txt file that reads as follows:

cmake_minimum_required(VERSION 3.4.1)

include_directories(
  build/liquidcore-addon/include/JavaScriptCore
)

add_library( js-lib SHARED IMPORTED )
set_target_properties(
  js-lib
  PROPERTIES IMPORTED_LOCATION
  ${PROJECT_SOURCE_DIR}/build/liquidcore-addon/jni/${ANDROID_ABI}/libliquidjs.so
)

target_link_libraries( js-lib )

I added this file to the native build targets in my build.gradle file. However, whenever I try to build the project, I get the following error: CMake Error at CMakeLists.txt:14 (target_link_libraries): Cannot specify link libraries for target "js-lib" which is not built by this project.

If I try to build without the CMakeLists.txt, the build succeeds, but trying to instantiate as JSContext object throws java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/collection/LongSparseArray. I assume this is because the C++ libraries have not been built properly.

I have two questions from this that I'm trying to resolve:

  1. Do I need to install the C++ libraries in order to use JSContext and associated objects?
  2. If so, why is the project failing to build? This appears to be a problem with my CMakeLists.txt file, but I don't know what the issue is.

Any guidance much appreciated!

Arvoreniad commented 4 years ago

I fixed my issue. Adding the details here in case someone else runs into the same problem.

To answer my question (1), you don't need to install the C++ libraries in order to use the V8 bindings. My confusion was caused by the fact that LiquidCore doesn't download the necessary JAR file until you build the project for the first time after you've added the dependencies to the gradle file. After that, it will work as expected.

However, after this, creating a new JSContext still caused java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/collection/LongSparseArray. I fixed this by adding the following lines to my gradle.properties file:

android.enableJetifier=true
android.useAndroidX=true

I then migrated the app to AndroidX (using the option in Android Studio under the Refactor menu). After that, it compiled and ran as expected.