GWT 2.7.0 Custom Linker Problem - <module>.nocache.js Artifact content mismatches file

208 views
Skip to first unread message

bobbit...@gmail.com

unread,
Jun 24, 2015, 2:40:56 PM6/24/15
to google-web-tool...@googlegroups.com
To solve an issue with our particular use of GWT, we implement our own "post" Linker for GWT.  This post linker appends a block of JS code to the end of <module>.nocache.js, by detecting the nocache.js file when it's passed to the link() command in the ArtifactSet, and replacing it with a new Artifact that's actually the original Artifact with our code appended.  This works fine in production mode, and our appended code shows up in <module>.nocache.js in the file system.

However, when Eclipse is used to run the server on port 8888 with GWT 2.7.0 in SuperDevMode, all heck breaks loose:  Our post linker still sees the original content in the <module>.nocache.js file (i.e., the same content we see for production mode).  However, this content is not then present in the <module>.nocache.js file in the file system.  Instead, that file contains totally different content.  In particular, there's a comment:

**
 * This startup script is used when we run superdevmode from an app server.
 */


Needless to say, since the linker is not ever served this content in any Artifact, we can't append anything to it.  So the questions arise:
  • Why are the post-linkers fed misleading content for the <module>.nocache.js file Artifact that doesn't represent what will be the file system content of that file?
  • Is there any way to gain access to the Artifact that actually contains the "fake" app server JS code that is written into <module>.nocache.js so it can be modified?
  • How do I control the order of my post linker within the set of other post linkers?  I set it as a post linker with a pragma, but say I want it to be the last post linker?
If there is some alternate means to hook loading of <module>.nocache.js, that would also work for our application, as long as it's synchronously executed (as is JS code appended to <module>.nocache.js).

Jens

unread,
Jun 24, 2015, 4:42:47 PM6/24/15
to google-web-tool...@googlegroups.com

  • Why are the post-linkers fed misleading content for the <module>.nocache.js file Artifact that doesn't represent what will be the file system content of that file?
A production compile and SuperDevMode work different because SDM needs to load up-to-date code from the CodeServer and also tells the CodeServer to recompile the app when you reload the page. To do so SDM creates a special <module>.nocache.js file and stores it in our war/launcherDir folder so it will be deployed. There is no linking involved here, its a helper file that just has the same name as the file produced by GWT compilation later. When you reload the page that file will call the URL


which produces some JS that reads some information of your browser, etc. and finally triggers the recompile on the SDM CodeServer by calling the URL

http://localhost:9876/recompile/<modulename>?<list of computed deferred binding properties>

When your app has been recompiled the JS from the recompile-requester will place a script tag into your host page pointing to the newly compiled/generated <module>.nocache.js file from the CodeServer. That file always lives under

http://localhost:9876/<modulename>/<modulename>.nocache.js

So when you open this URL in your browser you should see the content that you have added during the linking process, as thats the real file produced by the GWT compiler on each recompile.


  • Is there any way to gain access to the Artifact that actually contains the "fake" app server JS code that is written into <module>.nocache.js so it can be modified?
No as its not an Artifact that goes through the linking process. It is just a helper file directly written to disk by the CodeServer. You can see that here:


 
  • How do I control the order of my post linker within the set of other post linkers?  I set it as a post linker with a pragma, but say I want it to be the last post linker?

According to http://www.gwtproject.org/doc/latest/DevGuideLinkers.html they are executed in reverse lexical order based on their name. 


-- J.


bobbit...@gmail.com

unread,
Jun 29, 2015, 11:17:01 AM6/29/15
to google-web-tool...@googlegroups.com
On Wednesday, June 24, 2015 at 3:42:47 PM UTC-5, Jens wrote:

  • Why are the post-linkers fed misleading content for the <module>.nocache.js file Artifact that doesn't represent what will be the file system content of that file?
A production compile and SuperDevMode work different because SDM needs to load up-to-date code from the CodeServer and also tells the CodeServer to recompile the app when you reload the page. To do so SDM creates a special <module>.nocache.js file and stores it in our war/launcherDir folder so it will be deployed. There is no linking involved here, its a helper file that just has the same name as the file produced by GWT compilation later. When you reload the page that file will call the URL


The problem is that when the original (non-hacked) <module>.nocache.js is loaded by the project's HTML, it executes synchronously before any additional <script> tags in that HTML page.  However, the special <module>.nocache.js provided by the server installs a listener that injects:that URL (recompiler-requestor) only after the page has finished loading - so after all the subsequent script tags in the HTML have already executed.

For us there are actually two problems:
  • the real <module>.nocache.js is executed too late, after the HTML page has already finished loading
  • when it does run, because it's running asynchronously, the hook we inject which uses document.write() encounters the error "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened."
 
  • How do I control the order of my post linker within the set of other post linkers?  I set it as a post linker with a pragma, but say I want it to be the last post linker?

According to http://www.gwtproject.org/doc/latest/DevGuideLinkers.html they are executed in reverse lexical order based on their name. 

Yeah, I saw that, but looking in Eclipse at various stack frame variables while in our custom linker, the post linkers don't appear to be ordered by either fully qualified or unqualified class name.

Jens

unread,
Jun 29, 2015, 12:10:43 PM6/29/15
to google-web-tool...@googlegroups.com

  • when it does run, because it's running asynchronously, the hook we inject which uses document.write() encounters the error "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened."

Change the JS you added through your custom linker to not use document.write(). Instead use real DOM operations as that should fix the error you are seeing. 

But yeah you are right, the behavior is a bit different with SDM as it needs to wait for the CodeServer to complete compilation and provide the real *.nocache.js file.

-- J.
Reply all
Reply to author
Forward
0 new messages