Chrome LiveEdit and SDM

297 views
Skip to first unread message

Ivan Markov

unread,
Aug 31, 2014, 1:15:19 PM8/31/14
to google-web-tool...@googlegroups.com
(Background: I'm trying to further shorten the edit-compile-debug cycle by playing with hot-code swapping of recompiled JavaScript in Chrome (via Eclipse / SDBG))

GWT 2.7.0-SNAPSHOT, SDM mode, xsiframe linker (obviously), playing with LiveEdit from within Chromedevtools initially:
- Editing "<module>.nocache.js" works
- However editing "<module>-0.js" does not work (big surprise)

Problem 1: I think the "sourceURL=<module>-0.js" line at the end of the script should be present only if CrossSiteIframeLinker is running in "non-pretty /  production" mode. In pretty mode, where the <script> tag src attribute is directly modified to point to the CAGFG...AB.cache.js permutation this is probably just bringing confusion, no?

Unfortunately, fixing Problem 1 alone did not enable LiveEdit.
I think another issue (let's call it Problem 2) is that the xsiframe linker is creating the <iframe> & <script> tags dynamically using JavaScript DOM manipulations. There is some evidence on the internet that editing scripts injected that way is not supported.

I was thinking of solving Problem 2 by just switching to the sso (SingleScriptLinker) linker, but then:
(a) It is still not supported in SuperDevMode - https://code.google.com/p/google-web-toolkit/issues/detail?id=7722
(b) By looking at the source, it seems it is wrapping all the generated GWT code in enclosing functions, which are then called at the end of the script block. I don't think LiveEdit will be re-evaluating these, so this wrapping has to go somehow...

Any ideas?

Ray Cromwell

unread,
Aug 31, 2014, 1:33:13 PM8/31/14
to google-web-toolkit-contributors
Try using the xs linker instead.



--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/033a0106-49a2-4d66-aed0-5ee07d515c4d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Daniel Kurka

unread,
Sep 1, 2014, 3:55:25 AM9/1/14
to google-web-tool...@googlegroups.com
Hi Ivan,

why would you want to edit the JavaScript instead of editing your Java code?

How long does your compile take with the current GWT 2.7 Snapshot?

-Daniel





--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/033a0106-49a2-4d66-aed0-5ee07d515c4d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Google Germany GmbH
Dienerstr. 12
80331 München

Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschäftsführer: Graham Law, Katherine Stephens

Ivan Markov

unread,
Sep 1, 2014, 5:18:52 AM9/1/14
to google-web-tool...@googlegroups.com
Daniel,

I'm not planning to edit the generated JavaScript by hand. My idea is to remove the need to do webapp reloading. The problem with reloading the webapp is NOT that it takes a lot of time (it probably doesn't), but that if the webapp is a stateful one, reloading it on each SDM recompile means the developer has to essentially "start over" in reproducing the problem being debugged (e.g. navigating in the webapp, opening the relevant screens, clicking here and there, etc.).

This problem is not something new. It is well known and addressed when doing e.g. server-side or rich client development (HotSpot hot code replace; JRebel; "edit-and-continue" in the .NET / Win32 world, etc.)

How can webapp reloading be removed? By integrating SuperDevMode in Eclipse in such a way that:
(b) The JavaScript generated by the recompilation should be automatically pushed to Chrome via the Chrome Debugger wire protocol - without reloading the webapp

Both (a) and (b) are easy, except that (b) does not work. It does not work, because the way the xsiframe linker injects the permutation script in the DOM is not compatible with Chrome LiveEdit.


Ivan Markov

unread,
Sep 1, 2014, 5:43:53 AM9/1/14
to google-web-tool...@googlegroups.com
Ray,

Using the xs linker seems like a bad idea, as it combines the disadvantages of sso and the xsiframe: :)
(a) Like xsiframe, it injects <script> tags in the document body via JavaScript, which makes these script tags uneditable via Chrome LiveEdit
(b) Like sso, it uses the Module Pattern to wrap all GWT code in a function closure. I doubt that LiveEdit can replace the so-wrapped functions, even if problem (a) was solved somehow.

I think a better starting point would be the xsiframe linker, as it at least does not use the Module Pattern (right?) so at least problem (b) is gone.


31 август 2014, неделя, 20:33:13 UTC+3, Ray Cromwell написа:
Try using the xs linker instead.

On Sun, Aug 31, 2014 at 10:15 AM, Ivan Markov <ivan....@gmail.com> wrote:
(Background: I'm trying to further shorten the edit-compile-debug cycle by playing with hot-code swapping of recompiled JavaScript in Chrome (via Eclipse / SDBG))

GWT 2.7.0-SNAPSHOT, SDM mode, xsiframe linker (obviously), playing with LiveEdit from within Chromedevtools initially:
- Editing "<module>.nocache.js" works
- However editing "<module>-0.js" does not work (big surprise)

Problem 1: I think the "sourceURL=<module>-0.js" line at the end of the script should be present only if CrossSiteIframeLinker is running in "non-pretty /  production" mode. In pretty mode, where the <script> tag src attribute is directly modified to point to the CAGFG...AB.cache.js permutation this is probably just bringing confusion, no?

Unfortunately, fixing Problem 1 alone did not enable LiveEdit.
I think another issue (let's call it Problem 2) is that the xsiframe linker is creating the <iframe> & <script> tags dynamically using JavaScript DOM manipulations. There is some evidence on the internet that editing scripts injected that way is not supported.

I was thinking of solving Problem 2 by just switching to the sso (SingleScriptLinker) linker, but then:
(a) It is still not supported in SuperDevMode - https://code.google.com/p/google-web-toolkit/issues/detail?id=7722
(b) By looking at the source, it seems it is wrapping all the generated GWT code in enclosing functions, which are then called at the end of the script block. I don't think LiveEdit will be re-evaluating these, so this wrapping has to go somehow...

Any ideas?

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.

John Stalcup

unread,
Sep 1, 2014, 3:58:39 PM9/1/14
to google-web-tool...@googlegroups.com
you could try changing line 182 in Recompiler.java to register the "std" linker https://gwt.googlesource.com/gwt.git/+/2.5.1/dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java


To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/6d7bf5da-0ba5-48a1-b2f7-2dec9e74370b%40googlegroups.com.

John Stalcup

unread,
Sep 1, 2014, 4:00:15 PM9/1/14
to google-web-tool...@googlegroups.com

Ivan Markov

unread,
Sep 4, 2014, 7:13:56 AM9/4/14
to google-web-tool...@googlegroups.com
Thanks for the hint.
Any idea why the code server insists on using the xsiframe linker? 5 lines below your suggested fix there is even a check if the primary linker is a descendant of xsiframe.

Ivan Markov

unread,
Sep 6, 2014, 9:16:35 AM9/6/14
to google-web-tool...@googlegroups.com
I have some good news and some bad news...

The good news: 
None of my original suspicions as to why Chrome LiveEdit does not work are true.
Live editing works just fine when the script is injected in the page programmatically by another script using DOM manipulations (ala xsiframe linker). And even if there is a "//sourceURL=" hint at the end of it.

So the good news is that the xsiframe linker does not need any of the original changes I thought would be needed, and in theory should work out of the box.

The bad news:
Chrome LiveEdit seems to break simply when the script is too big:
- Above 10Mb, it is not editable at all from within Chromedevtools. I don't know whether this is a restriction of Chromedevtools, or of V8;
- But even below 10Mb, editing large script files usually leads to the browser getting stuck for some seconds and then simply crashing;

Next steps: 
(1) I'll try to check if LiveEdit would work with at least (very) small GWT projects;
(2) Splitting the large scripts into many smaller scripts may solve the problem? If yes, then the code splitting logic in the xsiframe linker which is currently incompatible with sourcemaps should be implemented in a way compatible with sourcemaps - somehow;
(3) Maybe file bugs to Chromium?

Ivan Markov

unread,
Sep 6, 2014, 12:05:52 PM9/6/14
to google-web-tool...@googlegroups.com
Another option would be to abandon Chrome LiveEdit completely in favor of a do-it-yourself approach.
JavaScript does allow functions and variables redefinition, so maybe we can just inject another <script> inside the iframe with the newly recompiled permutation? 
(To have this instantaneous, only a script containing the changed types should be injected, however I'm not sure if/what needs to be fixed so that sourcemaps continue to work after that.)

Ray Cromwell

unread,
Sep 6, 2014, 2:42:38 PM9/6/14
to google-web-toolkit-contributors

HotPatching via recompilation will require significant work in SDM. If you just did the naive thing and patched in the JS that changed, stuff would break:

1) clinit()s which have already been called would be restored, so classes would get initialized twice
2) some instance fields of the class would get reinitialized
3) callbacks held by JSNI closures might still point to old code in some circumstances I think

SDM mode would have to do minimally the following:
1) collect only the JS that actually changed
2) don't emit clinits for already live classes,  and if the user added a new clinit to an existing class or a new statically initialized field, force a full refresh
3) don't re-emit  field initializers for existing fields on classes, only for new added fields
4) if method signatures change, may have to force a full refresh
5) the code must be patched in via linker-dependent scope injection as if it were an AsyncFragment



--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/eeeb5252-162b-4381-a3fa-14da59fa9873%40googlegroups.com.

Brandon Donnelson

unread,
Nov 25, 2014, 12:56:13 PM11/25/14
to google-web-tool...@googlegroups.com
Hm, from what it sounds like, instead of hot patching, it'd be more practical and easier to change my debugging strategy and especially since the refresh time is so fast now using incremental compiles. I suppose I leave that behind for now. 

It seems more practical to refresh than fight the reality of hot patching, which is probably not what folks would want to hear. And this probably has to do with the design challenge for those who are debugging apps that with an authentication process to run through before they get to the widgets there working on, which docs could be used to help guide through this type of process.

Thanks for the feedback,
Brandon


On Saturday, September 6, 2014 11:42:38 AM UTC-7, Ray Cromwell wrote:

HotPatching via recompilation will require significant work in SDM. If you just did the naive thing and patched in the JS that changed, stuff would break:

1) clinit()s which have already been called would be restored, so classes would get initialized twice
2) some instance fields of the class would get reinitialized
3) callbacks held by JSNI closures might still point to old code in some circumstances I think

SDM mode would have to do minimally the following:
1) collect only the JS that actually changed
2) don't emit clinits for already live classes,  and if the user added a new clinit to an existing class or a new statically initialized field, force a full refresh
3) don't re-emit  field initializers for existing fields on classes, only for new added fields
4) if method signatures change, may have to force a full refresh
5) the code must be patched in via linker-dependent scope injection as if it were an AsyncFragment


On Sat, Sep 6, 2014 at 9:05 AM, Ivan Markov <ivan....@gmail.com> wrote:
Another option would be to abandon Chrome LiveEdit completely in favor of a do-it-yourself approach.
JavaScript does allow functions and variables redefinition, so maybe we can just inject another <script> inside the iframe with the newly recompiled permutation? 
(To have this instantaneous, only a script containing the changed types should be injected, however I'm not sure if/what needs to be fixed so that sourcemaps continue to work after that.)

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages