Java Bindings for V8

Related tags

Native J2V8
Overview

J2V8

Build Status Maven Central

J2V8 is a set of Java bindings for V8. J2V8 focuses on performance and tight integration with V8. It also takes a 'primitive first' approach, meaning that if a value can be accessed as a primitive, then it should be. This forces a more static type system between the JS and Java code, but it also improves the performance since intermediate Objects are not created.

We developed J2V8 as a high performance engine for our multi-platform mobile toolkit tabris.js and it is a great choice for executing JavaScript on Android devices.

Building J2V8

Building J2V8 requires building both the native parts and the Java library (.jar/.aar file). To build the native parts we first build V8 as a monolithic library and then statically link J2V8 to that. The Java parts are built with maven/gradle.

J2V8 uses a cross-platform, cross-compiling build-system written in Python.

For any further build instructions & details please read BUILDING.md

Tutorials

Articles

Presentations

Other Resources

Here is a list of articles I've written on J2V8 http://eclipsesource.com/blogs/tag/j2v8/.

Who is using J2V8?

Here are some projects that use J2V8:

License

The code is published under the terms of the Eclipse Public License, version 1.0.

Comments
  • additional Build-System features & fixes

    additional Build-System features & fixes

    Features

    • support for multiple build virtualization options per platform (Docker & Vagrant)
      • added Vagrant build support for the win32 target (should help with this requirement)
    • support for customizing platform builds for different OS vendors
      • added build support for alpine-linux (supercedes #289)
    • added nodejs.py utility script to package / manage the node.js code / binaries
      • adresses point 1.
      • lays some foundations for further development towards automated deployments & CI integration
      • #261, #257
    • added documentation headers & some more inline documentation for most py files
    • new --no-shutdown option for vagrant builds (keeps the used Vagrant VM running after a build is finished)
    • new --keep-native-libs option provides basic support for including different native libraries into a single JAR bundle
    • added an interactive mode for the build.py CLI
    • added support for "anti-steps" when running a build
      • e.g. all ~nodejs ~test runs all build-steps except for nodejs and test
    • documented new build-system features in BUILDING.md
    • split PlatformDetection code from LibraryLoading code & tried to use more normalized strings for platforms, vendors and architectures
    • updated & added some tests
    • when the Android emulator is running within Docker it now writes a logcat.txt file for debugging of the emulator status & potential problems

    Fixes

    • Issues #319, #311, #292, #188, #320
    • PRs #314
    • improved support for android testing (it's now also possible to run individual tests)
    • --node-enabled bug
    • many more smaller fixes & code improvements (see commit messages)
    opened by drywolf 92
  • Multi-Thread usage -> Crash due to desynchronized Isolates (pointers desync)

    Multi-Thread usage -> Crash due to desynchronized Isolates (pointers desync)

    A recent work of significantly increasing scalability of J2V8 by removing a lock between V8 instances and letting JAVA layer's lock V8 instance and isolate them caused number of issues (crashes). Some issues have been already patched (https://github.com/eclipsesource/J2V8/commit/8f8625015bc1314ee71cfab725d5d72f44979109) and others by passing explicitly Isolate in #308 and #310 but one crash is hard to solve due to inability to easily pass explicitly Isolate by using V8 API. There is also possibility that there maybe other places that could cause similar crash.

    An investigation effort was launched to find out why it crashes and the following lines of code have been identified:

    In class isolate.cpp

    String::Value::Value(v8::Local<v8::Value> obj) : str_(NULL), length_(0) {
      if (obj.IsEmpty()) return;
      i::Isolate* isolate = i::Isolate::Current();
      Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
      ENTER_V8(isolate);
      i::HandleScope scope(isolate);
      Local<Context> context = v8_isolate->GetCurrentContext();
      TryCatch try_catch(v8_isolate);
      Local<String> str;
      if (!obj->ToString(context).ToLocal(&str)) return;
      length_ = str->Length();
      str_ = i::NewArray<uint16_t>(length_ + 1);
      str->Write(str_);
    }
    

    Clearly as with issues #308 and #310 the isolate retrieved via a static method is from time tpo time not the correct one. This suggests a race condition or generally some threading issue. Further investigation shows that Isolates in V8 are in fact stored on thread locals. Even though many places V8's code have been updated to allow passing Isolate explicitly to methods and constructors, as it is visible the constructor that creates String::Value has not been updated or it was not supposed to be updated (unclear). Reading V8 code further reveals places where those ThreadLocals are managed: isolate.h

      // Find the PerThread for this particular (isolate, thread) combination
      // If one does not yet exist, return null.
      PerIsolateThreadData* FindPerThreadDataForThisThread();
    
      // Find the PerThread for given (isolate, thread) combination
      // If one does not yet exist, return null.
      PerIsolateThreadData* FindPerThreadDataForThread(ThreadId thread_id);
    
      // Discard the PerThread for this particular (isolate, thread) combination
      // If one does not yet exist, no-op.
      void DiscardPerThreadDataForThisThread();
    

    There is also a comment from the authors of V8 that the notion of accessing Isolates via ThreadLocals seems to be deprecated. Sadly, even as of 22 Jul 2017, master version of V8 still contains this TODO and the error prone and brittle accessing of Isolates via ThreadLocals in still the code.

    This code seems to prove that the concept of using Isolate::Current() and probably Isolate::GetCurrent() is deprecated:

      // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
      Isolate::Scope isolate_scope(v8_isolate);
      if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
        isolate->Init(NULL);
      }
    

    Due to Isolate::Current() it also looks that there is hacky code which does not bring confidence that V8 could flawlessly operate in the multi-threaded environment.

    Having said that it is not 100% clear if the actual bug is in J2V8 code by misusing V8 API or if the crash happens and a defect is in fact in V8 code that thread locals do not maintain a proper state and hold the correct pointer of Isolate at all times of the lifecycle of the V8.

    What does not help in the situation is that V8's locks are binary and V8's are counting semaphores. This is a different paradigm between the two and in theory could cause desynchronization of those locks.

    IMHO, there are a few schools of thought how to continue further:

    1. Find out why V8 and J2V8 Isolates pointers get desychronized and fix the problem. This is assuming that defect is in the J2V8 code and that J2V8 is incorrectly using V8 API. One possibility here could be to turn J2V8 locks also in counting semaphores so that models of locks stay in sync (despite the fact that counting semaphores are way complicated than binary ones.

    2. Patch V8 in such a way that actually refactoring is performed to remove i::Isolate::Current(); and Isolate::GetCurrent() as they want this anyway, see their TODO entry above. Once refactoring is done, submit PR to V8 codebase. Replace all places where Isolate is retrieved via static method and usage of ThreadLocals with explicitly passing Isolate (tedious code and really verbose but maybe less brittle). Here the bare minimum would be find all places where J2V8 relies on methods that in fact used Isolate::Current, etc and remove them by passing Isolate explicitly. Stretch goal for PR to V8 could be in fact to fix all places where such code is used in the code-base - removing altogether completely Isolate::GetCurrent();

    3. Consider some sort of silly patch and workaround that sets the Isolate pointer from J2V8's v8Runtime on ThreadLocal upon every high level entry to V8 method, this would mean that calls to Isolate::Current would be correct. Such hacky patch ideally should also destroy thread local before setting it and clear and or possibly clear that again just before leaving the top level API method call. This is a bit mine field though.

    4. Refactor J2V8 code in such a way that it avoids using classes, constructors and methods that take Isolate from ThreadLocal like fire. This may require that one needs to fine alternatives to write code, e.g. turn Local into some other String than String::String::Value (which has a busted constructor that retrieves implicitly Isolate)

    Crash report:

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=0x00007fc4c9a6b872, pid=38, tid=0x00007fc4cb117700
    #
    # JRE version: Java(TM) SE Runtime Environment (8.0_131-b11) (build 1.8.0_131-b11)
    # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode linux-amd64 compressed oops)
    # Problematic frame:
    # C  [libj2v8_linux_x86_64.so+0x56f872]  v8::String::Value::Value(v8::Local<v8::Value>)+0x52
    #
    # Core dump written. Default location: //core or core.38
    #
    # If you would like to submit a bug report, please visit:
    #   http://bugreport.java.com/bugreport/crash.jsp
    # The crash happened outside the Java Virtual Machine in native code.
    # See problematic frame for where to report the bug.
    #
    
    ---------------  T H R E A D  ---------------
    
    Current thread (0x00007fc36000b800):  JavaThread "http-nio-8080-exec-20" daemon [_thread_in_native, id=156, stack(0x00007fc4cb017000,0x00007fc4cb118000)]
    
    siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000008ce8
    
    Registers:
    RAX=0x0000000000000000, RBX=0x0000000000000000, RCX=0x0000000000000000, RDX=0x00007fc4cb117a30
    RSP=0x00007fc4cb1154a0, RBP=0x00007fc4cb115540, RSI=0x00007fc3ec05d0a8, RDI=0x0000000000000002
    R8 =0x0000000000000000, R9 =0x00000359975ba600, R10=0x00007fc508f55a08, R11=0x00001e1900000000
    R12=0x00007fc4cb1154d0, R13=0x00000000f858bb40, R14=0x00007fc4cb115990, R15=0x00007fc3ec05d0a8
    RIP=0x00007fc4c9a6b872, EFLAGS=0x0000000000010246, CSGSFS=0x0000000000000033, ERR=0x0000000000000004
      TRAPNO=0x000000000000000e
    
    Top of Stack: (sp=0x00007fc4cb1154a0)
    0x00007fc4cb1154a0:   0000000000000005 00007fc4cb115510
    0x00007fc4cb1154b0:   00007fc4cb1154e0 00003efbe57060c7
    0x00007fc4cb1154c0:   0000000000000002 00003efbe5706001
    0x00007fc4cb1154d0:   00007fc4cb1154c0 0000000000000030
    0x00007fc4cb1154e0:   000000000000bba1 10f049c554aa7700
    0x00007fc4cb1154f0:   00002a8ba937af31 00007fc3ec05d0a8
    0x00007fc4cb115500:   0000000000000000 10f049c554aa7700
    0x00007fc4cb115510:   00007fc3ec054b40 00000000c53e7db8
    0x00007fc4cb115520:   0000000000000000 00000000f858bb40
    0x00007fc4cb115530:   00007fc3ec054b40 00007fc36000b800
    0x00007fc4cb115540:   00007fc4cb1159c0 00007fc4c9a268e4
    0x00007fc4cb115550:   00007fc4cb115598 00000000e570ed5a
    0x00007fc4cb115560:   00007fc4cb115a20 00007fc508f40b10
    0x00007fc4cb115570:   00007fc4cb1159f0 00007fc36000b9f8
    0x00007fc4cb115580:   00002a79af68beb1 0000000c00000000
    0x00007fc4cb115590:   0000000c00000000 0000000c00000000
    0x00007fc4cb1155a0:   00003efbe5736961 0000000c00000000
    0x00007fc4cb1155b0:   00007fc3ec05d0a8 00007fc3ec05d0a8
    0x00007fc4cb1155c0:   0000000000000000 00002a8ba937ace9
    0x00007fc4cb1155d0:   00007fc508f4cd50 0000000000000003
    0x00007fc4cb1155e0:   00007fc4cab4ec6c 00007fc4cb115718
    0x00007fc4cb1155f0:   00002a252da3d6f1 0000000100000000
    0x00007fc4cb115600:   00007fc4cb1156e0 00007fc4c9c37223
    0x00007fc4cb115610:   00007fc4cb115620 00007fc4c9d47379
    0x00007fc4cb115620:   00007fc4cb115680 00002a252da04241
    0x00007fc4cb115630:   00007fc3ec064720 00000003c9d4703c
    0x00007fc4cb115640:   00007fc508f4cd50 00007fc3ec05d0b8
    0x00007fc4cb115650:   0000000000000000 0000000000000000
    0x00007fc4cb115660:   00007fc3ec05d0a8 00007fc3ec05d0a8
    0x00007fc4cb115670:   00000359975ba6c9 00000359975ba6c9
    0x00007fc4cb115680:   00000359975ba6c9 00000359975ba6c9
    0x00007fc4cb115690:   00000359975ba6c8 000026df57c04ca9 
    
    Instructions: (pc=0x00007fc4c9a6b872)
    0x00007fc4c9a6b852:   84 f5 00 00 00 48 8b 05 e2 23 0a 01 49 89 fe 49
    0x00007fc4c9a6b862:   89 f7 4c 8d 65 90 8b 38 e8 21 d0 f6 ff 48 89 c3
    0x00007fc4c9a6b872:   44 8b a8 e8 8c 00 00 48 89 85 70 ff ff ff c7 80
    0x00007fc4c9a6b882:   e8 8c 00 00 03 00 00 00 48 8b 80 28 8d 00 00 48 
    
    Register to memory mapping:
    
    RAX=0x0000000000000000 is an unknown value
    RBX=0x0000000000000000 is an unknown value
    RCX=0x0000000000000000 is an unknown value
    RDX=0x00007fc4cb117a30 is pointing into the stack for thread: 0x00007fc36000b800
    RSP=0x00007fc4cb1154a0 is pointing into the stack for thread: 0x00007fc36000b800
    RBP=0x00007fc4cb115540 is pointing into the stack for thread: 0x00007fc36000b800
    RSI=0x00007fc3ec05d0a8 is an unknown value
    RDI=0x0000000000000002 is an unknown value
    R8 =0x0000000000000000 is an unknown value
    R9 =0x00000359975ba600 is an unknown value
    R10=0x00007fc508f55a08 is an unknown value
    R11=0x00001e1900000000 is an unknown value
    R12=0x00007fc4cb1154d0 is pointing into the stack for thread: 0x00007fc36000b800
    R13=0x00000000f858bb40 is an oop
    [Ljava.lang.Object; 
     - klass: 'java/lang/Object'[]
     - length: 3
    R14=0x00007fc4cb115990 is pointing into the stack for thread: 0x00007fc36000b800
    R15=0x00007fc3ec05d0a8 is an unknown value
    
    
    Stack: [0x00007fc4cb017000,0x00007fc4cb118000],  sp=0x00007fc4cb1154a0,  free space=1017k
    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    C  [libj2v8_linux_x86_64.so+0x56f872]  v8::String::Value::Value(v8::Local<v8::Value>)+0x52
    C  [libj2v8_linux_x86_64.so+0x52a8e4]  getResult(JNIEnv_*, _jobject*&, long, v8::Local<v8::Value>&, int)+0x732
    C  [libj2v8_linux_x86_64.so+0x518be4]  Java_com_eclipsesource_v8_V8__1executeFunction__JIJLjava_lang_String_2J+0x1fb
    J 10189  com.eclipsesource.v8.V8._executeFunction(JIJLjava/lang/String;J)Ljava/lang/Object; (0 bytes) @ 0x00007fc4f8b9b14d [0x00007fc4f8b9b080+0xcd]
    J 12892 C2 com.eclipsesource.v8.V8Object.executeJSFunction(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object; (279 bytes) @ 0x00007fc4f9fff508 [0x00007fc4f9fff1c0+0x348]
    J 13578 C2 pubse.ecs.system.renderer.servlet.j2v8.PoolingJ2V8JavaScriptRenderer.apply(Lde/mobile/ecs/World;)V (340 bytes) @ 0x00007fc4fab1cfa4 [0x00007fc4fab1c780+0x824]
    J 13092 C2 pubse.ecs.system.renderer.ResponseRenderer.apply(Lde/mobile/ecs/World;)V (79 bytes) @ 0x00007fc4fa92d3b4 [0x00007fc4fa92d020+0x394]
    J 11516 C2 com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed()Ljava/lang/Object; (91 bytes) @ 0x00007fc4fa680350 [0x00007fc4fa67a3e0+0x5f70]
    J 13634 C2 pubse.config.InboundModule$Monitor.invoke(Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; (70 bytes) @ 0x00007fc4f9cea5bc [0x00007fc4f9cea4a0+0x11c]
    J 11516 C2 com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed()Ljava/lang/Object; (91 bytes) @ 0x00007fc4fa67a560 [0x00007fc4fa67a3e0+0x180]
    J 12832 C2 pubse.tomcat.handler.ServletRouter$$Lambda$188.handle(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V (10 bytes) @ 0x00007fc4faa54520 [0x00007fc4faa53be0+0x940]
    J 11093 C2 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (574 bytes) @ 0x00007fc4f969e020 [0x00007fc4f969dee0+0x140]
    J 12551 C2 org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljavax/servlet/FilterChain;)V (402 bytes) @ 0x00007fc4fa992a80 [0x00007fc4fa9917c0+0x12c0]
    J 11093 C2 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (574 bytes) @ 0x00007fc4f969e328 [0x00007fc4f969dee0+0x448]
    J 12771 C2 pubse.util.ServletFilters$Utf8EncodingFilter.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljavax/servlet/FilterChain;)V (21 bytes) @ 0x00007fc4faa25180 [0x00007fc4faa24da0+0x3e0]
    J 11093 C2 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (574 bytes) @ 0x00007fc4f969e328 [0x00007fc4f969dee0+0x448]
    J 12707 C2 pubse.util.ServletFilters$LoggingFilter.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljavax/servlet/FilterChain;)V (76 bytes) @ 0x00007fc4fa3bcfe8 [0x00007fc4fa3bcbe0+0x408]
    J 11093 C2 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (574 bytes) @ 0x00007fc4f969e328 [0x00007fc4f969dee0+0x448]
    J 13553 C2 org.apache.catalina.core.StandardWrapperValve.invoke(Lorg/apache/catalina/connector/Request;Lorg/apache/catalina/connector/Response;)V (1389 bytes) @ 0x00007fc4fa464fec [0x00007fc4fa464e00+0x1ec]
    J 12726 C2 org.apache.catalina.authenticator.AuthenticatorBase.invoke(Lorg/apache/catalina/connector/Request;Lorg/apache/catalina/connector/Response;)V (903 bytes) @ 0x00007fc4fa5b2900 [0x00007fc4fa5b1980+0xf80]
    J 12739 C2 org.apache.catalina.core.StandardHostValve.invoke(Lorg/apache/catalina/connector/Request;Lorg/apache/catalina/connector/Response;)V (402 bytes) @ 0x00007fc4faa03420 [0x00007fc4faa030c0+0x360]
    J 13494 C2 org.apache.catalina.connector.CoyoteAdapter.service(Lorg/apache/coyote/Request;Lorg/apache/coyote/Response;)V (805 bytes) @ 0x00007fc4fa105994 [0x00007fc4fa1054a0+0x4f4]
    J 13979 C2 org.apache.coyote.http11.AbstractHttp11Processor.process(Lorg/apache/tomcat/util/net/SocketWrapper;)Lorg/apache/tomcat/util/net/AbstractEndpoint$Handler$SocketState; (1128 bytes) @ 0x00007fc4f9b0f65c [0x00007fc4f9b0f020+0x63c]
    J 13493 C2 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(Lorg/apache/tomcat/util/net/SocketWrapper;Lorg/apache/tomcat/util/net/SocketStatus;)Lorg/apache/tomcat/util/net/AbstractEndpoint$Handler$SocketState; (1073 bytes) @ 0x00007fc4fa475960 [0x00007fc4fa475480+0x4e0]
    J 13115 C2 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun()V (603 bytes) @ 0x00007fc4fa0607fc [0x00007fc4fa060680+0x17c]
    J 12608 C2 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run()V (79 bytes) @ 0x00007fc4fa49626c [0x00007fc4fa4961c0+0xac]
    J 13557% C2 java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V (225 bytes) @ 0x00007fc4fa57c134 [0x00007fc4fa57bf20+0x214]
    j  java.util.concurrent.ThreadPoolExecutor$Worker.run()V+5
    j  org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run()V+4
    j  java.lang.Thread.run()V+11
    v  ~StubRoutines::call_stub
    V  [libjvm.so+0x691d16]  JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x1056
    V  [libjvm.so+0x692221]  JavaCalls::call_virtual(JavaValue*, KlassHandle, Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x321
    V  [libjvm.so+0x6926c7]  JavaCalls::call_virtual(JavaValue*, Handle, KlassHandle, Symbol*, Symbol*, Thread*)+0x47
    V  [libjvm.so+0x72da50]  thread_entry(JavaThread*, Thread*)+0xa0
    V  [libjvm.so+0xa76833]  JavaThread::thread_main_inner()+0x103
    V  [libjvm.so+0xa7697c]  JavaThread::run()+0x11c
    V  [libjvm.so+0x927568]  java_start(Thread*)+0x108
    
    opened by matiwinnetou 49
  • Build native JNI library with a consolidated CMake toolchain (cross-platform)

    Build native JNI library with a consolidated CMake toolchain (cross-platform)

    @irbull I started replacing the static Visual Studio project files with CMake scripts in my fork.

    This is the groundwork to consolidate all build scripts & steps into a single build script toolchain eventually. Currently I wrote & tested the scripts only for Windows builds (since that's what I'm using J2V8 on), but I would continue work on support for the other platforms if you would be interested in a PR ?

    opened by drywolf 35
  • J2V8 native library not loaded - only on SDK 23

    J2V8 native library not loaded - only on SDK 23

    Target SDK: 23 Device: Nexus 6P, Nexus 5X with Marshmallow

    java.lang.IllegalStateException:J2V8 native library not loaded. java.lang.UnsatisfiedLinkError: com.android.tools.fd.runtime.IncrementalClassLoader$DelegateClassLoader[,nativeLibraryDirectories=[/data/app/com.gettaxi.dbx.android-1/lib/arm64, /data/app/com.gettaxi.dbx.android-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64] couldn't find "libj2v8.so"

    Shared libraries that have text relocations are now rejected. This is documented here: https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-runtime

    You'll have to fix them, which means you need to have access to the native code and NDK prepared. Easiest workaround is to add -fpic or -fPIC to your LOCALC_FLAGS in your Android.mk file, and then rebuild the libraries.

    opened by parahall 33
  • static lock in the j2v8?

    static lock in the j2v8?

    We are trying to write a new page with server side rendering using j2v8 and ReactJS.

    It works kinda ok so far (including leaving it overnight with some scalability tests) but not as well we we will need. We are using a V8 pool with Apache commons so each thread from tomcat is accessing instance from the pool. Currently pool is maximally expanding to 20 items. We are only using V8 without NodeJS. What we found is the following.

    On one concurrent user the page renders very fast, 20 ms and page is relatively complex (data model + UI), on 10 concurrent users suddenly (after pool heats up) everything slows down dramatically. From 20 ms per user to 500 ms.

    After digging more and more I found this to be expensive an operation:

    Object modelAttributes = V8ObjectUtils.getV8Result(v8, model);
    

    This map that is passed from backend is a bit complex and nested but not too much, I could post it as well. It is really slow to convert this Java map to j2v8 V8 object map. Is it possible that there is some sort of static variable shared between V8 instances on the native level that is doing blocking?

    opened by matiwinnetou 31
  • Support 64-bit architectures

    Support 64-bit architectures

    According to this post https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html In August 2019, Google Play will require that new apps and app updates with native libraries provide 64-bit versions in addition to their 32-bit versions.

    Do you plan to support for 64-bit architectures?

    opened by ilyamuromets 29
  • cross-platform, cross-compile build toolchain

    cross-platform, cross-compile build toolchain

    This adds an easy-to-use, automated build toolchain that should replace the previous shell scripts and manual labor that is necessary to produce a working & tested build for all of the platforms & architectures that J2V8 should support.

    see #232 and #261

    Note: I left most of the existing shell scripts and Dockerfiles in place, but once this PR is merged we should go ahead and clean up everything that is deprecated by this PR.

    Thanks

    opened by drywolf 21
  • Multithread support

    Multithread support

    I know that javascript isn't support multiple threads, and what I need is creating multiple V8 engine instances on different threads and access this engine instances parallel.

    At this time, i can create multiple V8 engine instances, all the instances can be accessed from one single thread, because the V8 class stores the thread which created the first instance in a static field called thread, and later every method call the checkThread() method.

    I want to use V8 in a server environment where every request creates a new V8 instance and execute some script in it and after kill it. And every request has a separated thread. But now I can't do this.

    opened by dipacs-ds 21
  • ToObject: It is more thread safe to use isolate passed explicitly rather than relying on it retrieved via a static call in constructor.

    ToObject: It is more thread safe to use isolate passed explicitly rather than relying on it retrieved via a static call in constructor.

    Fixes #309. Perhaps there is more elegant fix but this already helps us in production on multi concurrent access and our rendering pool from V8s to serve pages.

    opened by matiwinnetou 19
  • JVM crash seemingly at random on 64-bit Windows

    JVM crash seemingly at random on 64-bit Windows

    We're seeing random JVM crashes on 64-bit Windows when calling J2V8 methods. We only encounter them when running our main application, and have been unable to isolate the issue in a JUnit test. Crash logs are here: https://gist.github.com/ccantill/42826929a65576823920 and https://gist.github.com/ccantill/c9c9d70ece25eb69f3fe Any hints as to what could be causing this or how to avoid this issue would be most welcome.

    opened by ccantill 19
  • Add support to 64 bit devices for Android

    Add support to 64 bit devices for Android

    Today you support only x86 and arm v7, devices with x86_64 for example can't run your code. Please add more jni libs for 64 bit.. This is the error I've got today:

    Caused by: java.lang.UnsatisfiedLinkError: Could not load J2V8 library. Reasons:
    Couldn't load j2v8_android_x86_64 from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.my-app.apk"],nativeLibraryDirectories=[/data/app-lib/com.my-app-2, /vendor/lib, /system/lib, /system/lib/arm]]]: findLibrary returned null

    Thanks for this great site and support !!

    Thanks a lot for this great library

    opened by lidord 19
  • error when building windows-x64

    error when building windows-x64

    Command: build -t win32 -a x64 -ne

    WARNING: skipping build step "v8" (not configured and/or supported for platform "win32")

    Microsoft Windows [Versión 10.0.19045.2251] Updating Maven configuration (./docker/shared/pom.xml)... SHELL building win32@x64 => j2v8cmake -- Selecting Windows SDK version to target Windows 10.0.19045. CMake Error at CMakeLists.txt:15 (project): Failed to run MSBuild command:

    C:/Program Files (x86)/MSBuild/14.0/bin/MSBuild.exe
    

    to get the value of VCTargetsPath:

    Microsoft (R) Build Engine version 14.0.23107.0
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    Build started 23/11/2022 01:03:46 p. m..
    Project "C:\Users\popit\java\J2V8\cmake.out\win32.x64\CMakeFiles\3.25.0\VCTargetsPath.vcxproj" on node 1 (default targets).
    C:\Users\popit\java\J2V8\cmake.out\win32.x64\CMakeFiles\3.25.0\VCTargetsPath.vcxproj(14,2): error MSB4019: The imported project "C:\Microsoft.Cpp.Default.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
    Done Building Project "C:\Users\popit\java\J2V8\cmake.out\win32.x64\CMakeFiles\3.25.0\VCTargetsPath.vcxproj" (default targets) -- FAILED.
    
    Build FAILED.
    
    "C:\Users\popit\java\J2V8\cmake.out\win32.x64\CMakeFiles\3.25.0\VCTargetsPath.vcxproj" (default target) (1) ->
      C:\Users\popit\java\J2V8\cmake.out\win32.x64\CMakeFiles\3.25.0\VCTargetsPath.vcxproj(14,2): error MSB4019: The imported project "C:\Microsoft.Cpp.Default.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
    
        0 Warning(s)
        1 Error(s)
    
    Time Elapsed 00:00:01.65
    

    Exit code: 1

    -- Configuring incomplete, errors occurred! See also "C:/Users/popit/java/J2V8/cmake.out/win32.x64/CMakeFiles/CMakeOutput.log". Traceback (most recent call last): File "build.py", line 18, in bex.execute_build(args) File "C:\Users\popit\java\J2V8\build_system\build_executor.py", line 322, in execute_build execute_build_step(target_compiler, target_step) File "C:\Users\popit\java\J2V8\build_system\build_executor.py", line 231, in execute_build_step build_system.build(build_step) File "C:\Users\popit\java\J2V8\build_system\build_structures.py", line 96, in build self.exec_build(config) File "C:\Users\popit\java\J2V8\build_system\shell_build.py", line 27, in exec_build self.exec_cmd(shell_str, config) File "C:\Users\popit\java\J2V8\build_system\build_structures.py", line 113, in exec_cmd self.__exec_cmd_core(cmd, config, config.build_cwd) File "C:\Users\popit\java\J2V8\build_system\build_structures.py", line 122, in __exec_cmd_core utils.execute(cmd, cwd) File "C:\Users\popit\java\J2V8\build_system\build_utils.py", line 157, in execute raise subprocess.CalledProcessError(return_code, cmd) subprocess.CalledProcessError: Command 'cd C:/Users/popit/java/J2V8 && python C:/Users/popit/java/J2V8/build_system/polyfills/mkdir.py ./cmake.out/win32.x64/ && cd ./cmake.out/win32.x64/ && python C:/Users/popit/java/J2V8/build_system/polyfills/rm.py CMakeCache.txt CMakeFiles/ && cmake ../../ -DJ2V8_TARGET_ARCH:STRING=x86_64 -DJ2V8_NODE_ENABLED:BOOL=TRUE -G"Visual Studio 14 2015 Win64" ' returned non-zero exit status 1

    opened by AngelGamer29JA 1
  • 【fix】fix-cross-path-attack-risk

    【fix】fix-cross-path-attack-risk

    The File. getAbsolutePath() method obtains the file path without filtering ". or. ". There is a risk of cross path attacks. It is recommended to use getCannonicalPath() to obtain the absolute path.

    https://developer.android.com/reference/java/io/File

    File.getAbsolutePath()方法获取文件路径,没有过滤“.\或.\”,存在跨路径攻击风险,推荐使用getCannonicalPath() 获取绝对路径。

    opened by captain6541 0
  • how can i pass java object in javascript and create new object in javascript?

    how can i pass java object in javascript and create new object in javascript?

    use j2v8 in android: class A{ public C methodA1(B b) { return b.methodB1(); }

    public B methodA2() {
    	return new B();
    }
    

    }

    class B{

    public C methodB1(){
    	return new C();
    }
    

    }

    class C{ public void methodC1(){

    }
    

    }

    then,what should i do to resolve this, i use registerJavaMethod but it report error like this:

    Unknown return type: class

    if use V8JavaAdapter.injectclass then can create new object like: let b1 = new B();

    and in java:

    v8 = V8.createV8Runtime(); V8Object v8Console = new V8Object(v8); v8.add('A',v8Console); v8Console.registerJavaMethod(value, method.getName(), method.getName(), parameterTypes); -- register A methodA1 then i use A.methodA1(b1) it report error: has argument 1 has type B, got com.eclipsesource.v8.V8Object, how to resolve it , Thank you!!

    opened by xjl2020 0
  • J2v8 Runtime Optimization

    J2v8 Runtime Optimization

    HI @irbull ,

    Hope you are doing well.

    We are using J2V8 library in one of our application which is a data hungry application, alot of data flowing in the system. the problem we are facing is because of runtime we are only able to process 20-30 records persecond, where as if I keep one runtime open count reach to the 1000 to 1100 records per second.

    Need you suggestion if we can keep one runtime open all the time and what are the pros and cons of it. Along with some steps to manage the running runtime (memory leaks etc).

    Thanks

    opened by vikasyadavhcl 0
  • [Question] How i can register java static methods in V8 runtime

    [Question] How i can register java static methods in V8 runtime

    Hi! this is only a question, i'm writing a tool to run JS Code from a JS File, but i can't see a way to make an java static method accessible via JavaScript, i saw the V8Object source code and i don't see anything about, and i tried using Class.getMethod, but this 3 lines blocked me: J2V8/src/main/java/com/eclipsesource/v8/V8Obiect.java at line 633

    Method method = object.getClass().getMethod(methodName, parameterTypes);
    method.setAccessible(true);
    v8.registerCallback(object, method, getHandle(), jsFunctionName, includeReceiver);
    

    At that moment, the variable object is an Class<?> object, and the methodName is obtained by class.getDeclaredMethods() -> .getName() inside a for loop, the problem is: Because of the variable object is a Class<?>, when the code call .getClass(), the code will access Class<Class> and will give an NoSuchMethodException because the method name that i give doesn't exists on the Class<Class> class.

    Is there a way to register java static methods with J2V8?

    opened by ghost 0
Owner
EclipseSource
EclipseSource
The missing bridge between Java and native C++

JavaCPP Commercial support: Introduction JavaCPP provides efficient access to native C++ inside Java, not unlike the way some C/C++ compilers interact

Bytedeco 4k Jan 8, 2023
Java Native Access

Java Native Access (JNA) The definitive JNA reference (including an overview and usage details) is in the JavaDoc. Please read the overview. Questions

Java Native Access 7.6k Jan 1, 2023
Java Abstracted Foreign Function Layer

jnr-ffi jnr-ffi is a Java library for loading native libraries without writing JNI code by hand, or using tools such as SWIG. Example package hellowor

The Java Native Runtime Project 1.1k Dec 31, 2022
Compile Java byte-code to native CPU's.

Java Grinder Compile Java bytecode to microcontroller assembly. Currently supporting MSP430, dsPIC, 6502/6510, 68000, MIPS, TMS9900, and Z80 with plat

Michael Kohn 396 Dec 23, 2022
Jssembly is a library that allows you to execute native assembly from Java.

jssembly Jssembly is a library that allows you to execute native assembly from Java via a JNI bridge. The goal is to provide wrappers and parsers for

David Titarenco 121 Jun 3, 2022
Low-overhead, non-blocking I/O, external Process implementation for Java

NuProcess NuProcess is proud to power Facebook's Buck build. A low-overhead, non-blocking I/O, external Process execution implementation for Java. It

Brett Wooldridge 644 Dec 29, 2022
Java Bindings for V8

J2V8 J2V8 is a set of Java bindings for V8. J2V8 focuses on performance and tight integration with V8. It also takes a 'primitive first' approach, mea

EclipseSource 2.3k Jan 4, 2023
Java/JNI bindings to libpostal for for fast international street address parsing/normalization

jpostal These are the Java/JNI bindings to libpostal, a fast, multilingual NLP library (written in C) for parsing/normalizing physical addresses aroun

openvenues 94 Oct 15, 2022
Java Foreign Linker bindings to Lua

jpanlua Java bindings to liblua using JEP 398: Foreign Linker API. Requires JDK 16 or above. Requires -Dforeign.restricted=permit JRE flag. Exports pa

Aly Cerruti 5 Dec 24, 2021
jextract is a tool which mechanically generates Java bindings from a native library headers.

Jextract jextract is a tool which mechanically generates Java bindings from a native library headers. This tools leverages the clang C API in order to

OpenJDK 120 Dec 30, 2022
RxJava bindings for JavaFX

RxJavaFX: JavaFX bindings for RxJava Read the free eBook Learning RxJava with JavaFX to get started. RxJavaFX is a lightweight library to convert Java

ReactiveX 513 Dec 27, 2022
Custom JavaFX bindings made easy with lambdas.

EasyBind EasyBind leverages lambdas to reduce boilerplate when creating custom bindings, provides a type-safe alternative to Bindings.select* methods

Tomas Mikula 146 May 29, 2022
Clojure bindings for the Chromium Embedded Framework

clj-cef Clojure bindings for the Chromium Embedded Framework Dependency: Rationale From https://bitbucket.org/chromiumembedded/cef/src/master/ Some us

Adrian 45 Nov 2, 2022
🍏 A collection of partial JNA bindings for various macOS frameworks. (e.g. Foundation, AppKit, etc.)

JNApple ?? A collection of partial JNA bindings for various macOS frameworks. (e.g. Foundation, AppKit, etc.) Usage These are just some common example

Iridescent 3 Jun 19, 2022
RxJava bindings for Android

RxAndroid: Reactive Extensions for Android Android specific bindings for RxJava 3. This module adds the minimum classes to RxJava that make writing re

ReactiveX 19.7k Dec 28, 2022
SynchronizeFX - a library for JavaFX 2 and later that enables property bindings between different JVMs

SynchronizeFX - a library for JavaFX 2 and later that enables property bindings between different JVMs, both on a local computer and over the network.

Manuel Mauky 8 Jul 24, 2020
Java 1-15 Parser and Abstract Syntax Tree for Java, including preview features to Java 13

JavaParser This project contains a set of libraries implementing a Java 1.0 - Java 14 Parser with advanced analysis functionalities. This includes pre

JavaParser 4.5k Jan 5, 2023
Convert Java to JSON. Convert JSON to Java. Pretty print JSON. Java JSON serializer.

json-io Perfect Java serialization to and from JSON format (available on Maven Central). To include in your project: <dependency> <groupId>com.cedar

John DeRegnaucourt 303 Dec 30, 2022
Microserver is a Java 8 native, zero configuration, standards based, battle hardened library to run Java Rest Microservices via a standard Java main class. Supporting pure Microservice or Micro-monolith styles.

Microserver A convenient modular engine for Microservices. Microserver plugins offer seamless integration with Spring (core), Jersey, Guava, Tomcat, G

AOL 936 Dec 19, 2022