This project is an add-on for the excellent J2V8 Project. It allows users to debug JS running in V8 using Chrome DevTools. Uses Stetho for communication with Chrome DevTools.

Overview

J2V8-Debugger

This project is an add-on for the excellent J2V8 Project.

It allows users to debug JS running in V8 using Chrome DevTools.

Uses Stetho for communication with Chrome DevTools.

Features

  • Debugging embedded V8 in Android app using Chrome DevTools.
  • Support setting/removing breakpoints, step into, step out and step over, variables inspection, etc.
  • Debugging embedded V8 is similar to Remote Debugging WebViews.
  • Access debuggable V8 in the app via chrome://inspect.

SetUp

Add JitPack repository in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}

Add dependency in gradle.build file of your app module

dependencies {
    implementation ('com.github.AlexTrotsenko:j2v8-debugger:0.2.3') // {
    //     optionally J2V8 can be excluded if specific version of j2v8 is needed or defined by other libs
    //     exclude group: 'com.eclipsesource.j2v8'
    // }
}

Note: current j2v8-debugger version is designed for J2V8 version 6.1+.

Use 0.1.2 when debugging of older J2V8 (4.6.0+) is required.

Usage

StethoHelper and V8Debugger are used for set-up of Chrome DevTools and V8 for debugging.

  1. Initialization Stetho in Application class.
    StethoHelper.initializeDebugger(context, scriptSourceProvider)
  1. Creation of debuggable V8 instance.

Use V8Debugger.createDebuggableV8Runtime() instead of V8.createV8Runtime()

    val debuggableV8Runtime : Future<V8> = V8Debugger.createDebuggableV8Runtime(v8Executor, globalAlias, enableLogging)

See sample project for more info.

Notes regarding J2V8 threads.

  • Creation and clean-up of V8 should run on fixed V8 thread.
  • Creation and clean-up of V8 Debugger should run on fixed V8 thread.
  • Debugging operation like set/remove breakpoint should run on fixed V8 thread.
  • Execution of any JS script/function should run on fixed V8 thread.

It's easier to implement such behaviour (especially from lib point of view) if single-threaded V8 executor is used.

This way all above mentioned operations would run on such executor.

Therefore lib api like V8Debugger.createDebuggableV8Runtime(v8Executor) is build with this concept in mind.

Later v8 executor will be passed to Chrome DevTools and used for performing debug-related operations.

If Guava is already used in project - MoreExecutors and ListenableFuture could be handy.

License

Copyright 2015 Alexii Trotsenko

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • I can`t debug my code

    I can`t debug my code

    Hello, I would like to ask a question. The version number of j2v8-debuger is 0.1.3, and the version of j2v8 is 5.0.103. I use the getOrCreateV8Debugger and initializeWithV8DebuggerInMainThread methods to initialize, but I always fail to debug my method, and there are breakpoints and breakpoints. The information can also be displayed in logcat

    2021-01-10 16:28:04.859 15807-16174 D/ChromeDevtoolsServer: onOpen
    2021-01-10 16:28:05.166 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":1,"method":"Page.canScreencast"}
    2021-01-10 16:28:05.205 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":2,"method":"Page.canEmulate"}
    2021-01-10 16:28:05.207 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Page.canEmulate
    2021-01-10 16:28:05.215 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":3,"method":"Worker.canInspectWorkers"}
    2021-01-10 16:28:05.227 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":4,"method":"Console.setTracingBasedTimeline","params":{"enabled":true}}
    2021-01-10 16:28:05.228 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Console.setTracingBasedTimeline
    2021-01-10 16:28:05.270 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":5,"method":"Console.enable"}
    2021-01-10 16:28:05.276 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":6,"method":"Network.enable"}
    2021-01-10 16:28:05.280 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":7,"method":"Page.enable"}
    2021-01-10 16:28:05.308 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":8,"method":"Page.getResourceTree"}
    2021-01-10 16:28:05.317 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":9,"method":"Debugger.enable"}
    2021-01-10 16:28:05.325 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":10,"method":"Debugger.setPauseOnExceptions","params":{"state":"none"}}
    2021-01-10 16:28:05.326 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Debugger.setPauseOnExceptions
    2021-01-10 16:28:05.328 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":11,"method":"Debugger.setAsyncCallStackDepth","params":{"maxDepth":0}}
    2021-01-10 16:28:05.329 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Debugger.setAsyncCallStackDepth
    2021-01-10 16:28:05.341 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":12,"method":"Debugger.skipStackFrames","params":{"script":"","skipContentScripts":false}}
    2021-01-10 16:28:05.342 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Debugger.skipStackFrames
    2021-01-10 16:28:05.344 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":13,"method":"Runtime.enable"}
    2021-01-10 16:28:05.345 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Runtime.enable
    2021-01-10 16:28:05.348 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":14,"method":"DOM.enable"}
    2021-01-10 16:28:05.399 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":15,"method":"CSS.enable"}
    2021-01-10 16:28:05.410 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":16,"method":"Worker.enable"}
    2021-01-10 16:28:05.411 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Worker.enable
    2021-01-10 16:28:05.413 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":17,"method":"Timeline.enable"}
    2021-01-10 16:28:05.413 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Timeline.enable
    2021-01-10 16:28:05.425 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":18,"method":"Database.enable"}
    2021-01-10 16:28:05.435 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":19,"method":"DOMStorage.enable"}
    2021-01-10 16:28:05.448 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":20,"method":"Profiler.enable"}
    2021-01-10 16:28:05.450 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":21,"method":"Profiler.setSamplingInterval","params":{"interval":1000}}
    2021-01-10 16:28:05.453 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":22,"method":"IndexedDB.enable"}
    2021-01-10 16:28:05.453 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: IndexedDB.enable
    2021-01-10 16:28:05.456 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":23,"method":"Page.setShowPaintRects","params":{"result":true}}
    2021-01-10 16:28:05.456 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Page.setShowPaintRects
    2021-01-10 16:28:05.459 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":24,"method":"Page.setShowDebugBorders","params":{"show":true}}
    2021-01-10 16:28:05.459 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Page.setShowDebugBorders
    2021-01-10 16:28:05.462 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":25,"method":"Page.setShowFPSCounter","params":{"show":true}}
    2021-01-10 16:28:05.463 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Page.setShowFPSCounter
    2021-01-10 16:28:05.475 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":26,"method":"Page.setContinuousPaintingEnabled","params":{"enabled":true}}
    2021-01-10 16:28:05.476 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Page.setContinuousPaintingEnabled
    2021-01-10 16:28:05.479 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":27,"method":"Page.setShowScrollBottleneckRects","params":{"show":true}}
    2021-01-10 16:28:05.479 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Page.setShowScrollBottleneckRects
    2021-01-10 16:28:05.482 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":28,"method":"Page.getNavigationHistory"}
    2021-01-10 16:28:05.483 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Page.getNavigationHistory
    2021-01-10 16:28:05.485 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":29,"method":"Worker.setAutoconnectToWorkers","params":{"value":true}}
    2021-01-10 16:28:05.486 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Worker.setAutoconnectToWorkers
    2021-01-10 16:28:05.487 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":30,"method":"Inspector.enable"}
    2021-01-10 16:28:05.499 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":31,"method":"Page.setShowViewportSizeOnResize","params":{"show":true,"showGrid":false}}
    2021-01-10 16:28:05.501 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":32,"method":"IndexedDB.requestDatabaseNames","params":{"securityOrigin":""}}
    2021-01-10 16:28:05.502 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: IndexedDB.requestDatabaseNames
    2021-01-10 16:28:05.504 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":33,"method":"Page.getNavigationHistory"}
    2021-01-10 16:28:05.505 15807-16174 D/ChromeDevtoolsServer: Method not implemented: Not implemented: Page.getNavigationHistory
    2021-01-10 16:28:05.507 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":34,"method":"Debugger.getScriptSource","params":{"scriptId":"dynamic-action-bar-ad-v1.1015.js"}}
    2021-01-10 16:28:05.533 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":35,"method":"Debugger.setBreakpointByUrl","params":{"lineNumber":468,"url":"http://app/dynamic-action-bar-ad-v1.1015.js","columnNumber":0,"condition":""}}
    2021-01-10 16:28:05.611 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":36,"method":"Debugger.setBreakpointByUrl","params":{"lineNumber":107,"url":"http://app/dynamic-action-bar-ad-v1.1015.js","columnNumber":0,"condition":""}}
    2021-01-10 16:28:05.631 15807-16174 V/ChromeDevtoolsServer: onMessage: message={"id":37,"method":"Debugger.setBreakpointByUrl","params":{"lineNumber":97,"url":"http://app/dynamic-action-bar-ad-v1.1015.js","columnNumber":0,"condition":""}}
    

    image

    please help me

    opened by zongxiaomi 8
  • remove unnecssary execute

    remove unnecssary execute

    v8Executor.execute was unnecessary here as this is only setting references, not calling v8. This was causing an issue depending on when bindV8ToChromeDebuggerIfReady was called.

    opened by jamie-houston 6
  • Fix for when debugger is stuck in paused state.

    Fix for when debugger is stuck in paused state.

    @AlexTrotsenko I found myself stuck in a paused j2v8 instance when Chrome DevTools wasn't even attached. I've added some checks here to prevent that, or resume if it happens.

    opened by jamie-houston 3
  • Fix for setting breakpoints while debugger is paused.

    Fix for setting breakpoints while debugger is paused.

    Changed add breakpoint function to execute instead of submit v8Executor call. If debugger was running it never submitted. Since the result doesn't rely on the the call we don't need to submit, we can just execute the v8Exector.

    The newly added breakpoint will not be hit until the script is executed again, but it will no longer kill DevTools when a breakpoint is set while debugging. Might be able to have it hit the breakpoint as well, but this is much better than before.

    opened by jamie-houston 3
  • Not working with latest v8 builds

    Not working with latest v8 builds

    V8 dropped the debug api that DebugHandler relies on so the debugger no longer works on later builds of v8. j2v8 will need to support the inspector api to re-enable debugging and j2v8-debugger will need to interface with that instead of the current DebugHandler.

    There’s an open PR on j2v8 to add support for the inspector api: https://github.com/eclipsesource/J2V8/pull/491

    opened by jhorst11 2
  • All keys of V8 objects are displayed twice.

    All keys of V8 objects are displayed twice.

    Reason: Chrome DevTools UI calls Runtime.getProperties() twice for unknown reason.

    todo: figure-out why this happens and how to avoid this if possible to have nice variables inspection UI.

    opened by AlexTrotsenko 2
  • StethoHelper.notifyScriptsChanged() currently closes Chrome DevTools connection.

    StethoHelper.notifyScriptsChanged() currently closes Chrome DevTools connection.

    Instead it should update script source code in Chrome DevTools.

    Reason: No simple "script changed" event was found in Chrome DevTools protocol.

    Currently as work-around, when Chrome DevTools is re-opened - it will show new version of JS scripts.

    opened by AlexTrotsenko 1
  • It's not possible to set break-point while debugging in progress.

    It's not possible to set break-point while debugging in progress.

    Reason:

    1. since J2V8 do not provide debugger.pause()/debugger.resume() methods - it's emulated by suspending v8 thread. 2.Since V8 thread is suspended - setting new breakpoint is not possible as it must run on the same V8 thread.

    Otherwise:

    • if we do return from Debugger.setBreakpointByUrl() until breakpoint is set - communication with Chrome DevTools is stuck.
    • if we return from this method before breakpoint is set in V8 - we can't remove it latter if error is happened during setting breakpoint. Thus UI has breakpoint where V8 will not stop. (There is only successful Debugger.scriptParsed event.)

    The best would be find if J2V8 can somehow pause execution "natively". See https://github.com/eclipsesource/J2V8/issues/411

    opened by AlexTrotsenko 1
  • Can not pause while script is running

    Can not pause while script is running

    Hi, When I running a script by ExecutorService.execute,cause this is a single thread executor,so before this script complete,I can not pause executing by V8Inspector.dispatchProtocolMessage("{ "id": 1, "method": "Debugger.pause" }"),actually,I can not do anything using dispatchProtocolMessage,because they're in diffrent thread,also can not use ExecutorService.execute to invoke V8Inspector.dispatchProtocolMessage because the script not complete this time.

    opened by zhangjiagege 1
  • JNI ERROR (app bug): local reference table overflow

    JNI ERROR (app bug): local reference table overflow

    Thank you Alex for your project.

    I have an error related to the log support (I think). When I get a lot of calls per second I get this error :

    image

    Everything works fine with j2v8 only.

    Thanks

    opened by benjaminbarbe 1
Owner
Alex Trotsenko
Alex Trotsenko
This project uses AAC and 3rd parties to present NFT collectibles

My NFT Android app This project uses AAC and 3rd parties to present NFT collectibles AAC(Android Archicture Components) Lifecycle-aware components Vie

LouisWu 2 Aug 21, 2022
λRPC allows using code with high-order functions as a service

λRPC Simple native RPC with high order functions support. Inspired by @altavir and Communicator. λRPC allows using code with high-order functions as a

Andrey Stoyan 5 May 18, 2022
Secure Preference Manager for android. It uses various Encryption to protect your application's Shared Preferences.

Secure-Pref-Manager ##Secure Preference Manager is a simple Library to help you protect your Shared Preferences. Secure Preference Manager for android

Prashant Solanki 72 Nov 25, 2022
Small utility used to add Homewizard Energy Socket tiles to Android Quick Settings

TileWizard [Alpha! Unstable!] Settings Result Functionality: Add up to 5 Wi-Fi Energy Sockets to Android Quick Settings. What do you need: Android dev

Niels Masdorp 2 Oct 19, 2021
📭 Extension to Ktor’s routing system to add object oriented routing and much more. 💜

?? Ktor Routing Extensions Extension to Ktor’s routing system to add object-oriented routing and much more. ?? Why? This extension library was created

Noelware 6 Dec 28, 2022
Expirable Disk Lru Cache is a secure(with encryption) wrapper for [DiskLruCache](https://github.com/JakeWharton/DiskLruCache) that allows expiring of key/value pairs by specifying evictionTimeSpan. It has very simple API.

ExpirableDiskLruCache ExpirableDiskLruCache is a wrapper for DiskLruCache that allows expiring of key/value pairs by specifying evictionTimeSpan. It h

Vijay Rawat 24 Oct 3, 2022
adds an option to the Android Sharesheet that allows you to save files to your device.

Save On Device adds an option to the Android Sharesheet that allows you to save files to your device. Download Get the app from the Google Play Store

null 24 Nov 29, 2022
Allows usage of iCalendar files with the Android calendar provider

ical4android ical4android is a library for Android that brings together iCalendar and Android. It's a framework for parsing and generating iCalendar r

bitfire web engineering 9 Dec 29, 2022
Sample project displaying process of OTP validation using firebase

OTP-Validation-using-firebase Sample project displaying process of OTP validation using firebase Screenshots Concepts used Integrated Firebase sdk for

Ankita Gaba 2 Jun 18, 2022
Android library to easily serialize and cache your objects to disk using key/value pairs.

Deprecated This project is no longer maintained. No new issues or pull requests will be accepted. You can still use the source or fork the project to

Anup Cowkur 667 Dec 22, 2022
A simple library for validating user input in forms using annotations.

ValidationKomensky for Android A simple library for validating user input in forms using annotations. Features: Validate all views at once and show fe

Inmite s.r.o. 512 Nov 20, 2022
A set of helper classes for using dagger 1 with Android components such as Applications, Activities, Fragments, BroadcastReceivers, and Services.

##fb-android-dagger A set of helper classes for using dagger with Android components such as Applications, Activities, Fragments, BroadcastReceivers,

Andy Dennie 283 Nov 11, 2022
Android Secure SharedPreferences Using Facebook Conceal Encryption

SharedChamber Android Project : SharedChamber on top of SharedPreferences using Facebook Conceal Description Conceal provides a set of Java APIs to pe

Hafiq 95 Nov 25, 2022
A lightweight library for config and using SharedPreferences

preferences-helper SharePreferences is very popular with any project and all most all project has SharePreferences for saving data. This library will

Khang Tran 23 May 8, 2021
recompose is a tool for converting Android layouts in XML to Kotlin code using Jetpack Compose.

recompose is a tool for converting Android layouts in XML to Kotlin code using Jetpack Compose.

Sebastian Kaspari 565 Jan 2, 2023
Generate helper methods for compose navigation using KSP

Compose NavGen Generate helper methods for compose navigation using KSP. ?? You can try it now, but it's still under development. ?? TODO Support defa

Kenji Abe 6 Feb 5, 2022
Extensions to encrypt DataStore using Tink

encrypted-datastore Extensions to encrypt DataStore using Tink. ⚠️ This tiny library will be maintained until an official solution for DataStore encry

Osip Fatkullin 53 Jan 1, 2023
Format numbers using a string pattern with this simple number formatted like ##-####-##

AndroidPattern Format numbers using a string pattern with this simple number formatted like ##-####-## Installation To get a Git project into your bui

Hussein Habibi Juybari 2 Oct 25, 2021