Re: [gwt-contrib] Phasing in a new, unified linker
On 2010-07-26, at 4:56 PM, John Tamplin wrote: Is the new linker designed to curtail extension, or to sanely encourage it? The existing primary linkers ended up getting extended in brittle ways. That's a good point. Let's make it a final class to start with, and open up extension points later as issues come up. There are no known needs for extensions at this point. Well, we do know there will be other linkers, and if there aren't extension points defined they will be done via cut-and-paste, which is what led to the current state we are in. I'd prefer if these classes weren't final, with a big warning that they may have breaking changes, even in minor revisions. I don't know if it's possible to predict every tweak that developers might want to make to the primary linker, but allowing a subclass to just specify a different template script certain covers a great deal of ground. With the current hybrid JS/Java approach to linking, I think it would be very difficult to properly support any extensibility. I think it might be possible to move the template JS files to GWT-translated code with extension points managed through rebinding and overriding. Until then, making changes that involve JS modifications effectively require you to cut and paste the whole file. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Adds a new CrossSiteIframeLinker. This linker works cross-site, (issue726802)
[manually forwarding to list due to subscription bug...] Wow, this looks great. This is exactly what I had imagined. Once dev mode is in place we should be able to switch dotspots over to this from our current custom linker. I was looking through the latest SelectionScriptLinker in trunk and didn't see where __COMPUTE_SCRIPT_BASE__ was defined. Is that new? http://gwt-code-reviews.appspot.com/726802/diff/1/3 File dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js (right): http://gwt-code-reviews.appspot.com/726802/diff/1/3#newcode88 dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js:88: (query.indexOf('gwt.hybrid') == -1); Is it worth trimming the old gwt.hosted baggage from here? http://gwt-code-reviews.appspot.com/726802/diff/1/3#newcode110 dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js:110: scriptFrame.style.cssText = 'position:absolute; width:0; height:0; border:none'; These should probably be !important to avoid user CSS accidentally styling them. Also, left: -1000px and top: -1000px, since absolute by default will place them at the end of the document potentially causing sizing issues. http://gwt-code-reviews.appspot.com/726802/diff/1/3#newcode265 dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js:265: softPermutationId = Number(strongName.substring(idx + 1)); This code is probably from the older linker, but Number(x) can also be written as +(x). http://gwt-code-reviews.appspot.com/726802/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] GPE JSNI formatting issues
Hey all, I've been fighting this JSNI formatting bug for a while now. The Google Plugin for Eclipse is basically flattening the indents on all my JSNI methods when using the format command. With the 'format on save' option chosen in Eclipse, it unformats all the JSNI in the file after a save operation: http://code.google.com/p/google-web-toolkit/issues/detail?id=4369 Any possibility of getting this on the roadmap for a quick fix? I've included a repro case in the bug that should demonstrate it in a clean Eclipse workspace. Thanks, Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors To unsubscribe, reply using remove me as the subject.
[gwt-contrib] Re: GPE JSNI formatting issues
I think I worded this more clearly in the bug, but it's actually the format save action that causes the JSNI to be unformatted, not the regular format action. The regular format action correctly ignores JSNI formatting, while the format save action seems to eat all of the leading whitespace. I had to paste the entire contents of an ancient version of Douglas Crockford's JSON library into a JSNI function earlier today as part of a unit test and I ended up with a few hundred lines of unindented circa-2005 Javascript after saving. :) On 2010-04-02, at 10:13 AM, Matt Mastracci wrote: Hey all, I've been fighting this JSNI formatting bug for a while now. The Google Plugin for Eclipse is basically flattening the indents on all my JSNI methods when using the format command. With the 'format on save' option chosen in Eclipse, it unformats all the JSNI in the file after a save operation: http://code.google.com/p/google-web-toolkit/issues/detail?id=4369 Any possibility of getting this on the roadmap for a quick fix? I've included a repro case in the bug that should demonstrate it in a clean Eclipse workspace. Thanks, Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors To unsubscribe, reply using remove me as the subject.
Re: [gwt-contrib] Proposal for including easyXDM as a new cross-domain Transport/RPC
Quickly browsing easyXDM and comparing to gwt-rpc-plus, it looks like the designs of both are very similar. easyXDM uses the term 'socket' where gwt-rpc-plus uses the term 'transport'. Both of them allow you to plug in the appropriate transport behind a socket-like interface. easyXDM adds some interesting additional functionality like automatic reliability and fragmenting. I believe that the current transport-focused interface used in both of these libraries is too limited to deal with some of the future technologies coming out of the HTML5 camp and too inflexible to deal with the use cases outside of being a dumb transport client for an RPC server somewhere else. I think that it would be beneficial to the GWT community if whatever transport layer makes it into GWT starts from the drawing board. Here's a brain-dump of some of the issues facing anyone attempting to tackle a generic transport library: 1. Unless a transport explicitly provides send and receive channels internally (ie: XMLHttpRequest), it's best to keep it as separate Sender/Receiver interfaces. There are a number of places where it's useful to compose two different transports (ie: see the next item - POST to send, postMessage to receive). This also allows you to handle inter-window RPC where requests come in through a receive channel and are sent back out over a send channel. 2. The best way I've found to deal with a cross-domain transport in HTML is to do a POST to a hidden iframe or ActiveXObject which either uses postMessage or window.name to send back its result. This transport needs to switch at runtime between the two methods: many of the browsers shipping today have supported versions out that don't do postMessage. Additionally, window.name won't be supported in modern browsers in the future: the spec mandates that it gets cleared during cross-domain navigation. 3. Channel metadata is very important to expose to clients. In the case of HTTP, this includes status codes and headers. In the case of postMessage, this includes the message domain and the sending window. In some cases you'll want to tunnel that metadata overtop of another transport via JSON. For instance, when you have a background page in a Chrome extension that accepts events over Chrome's internal messaging and converts them into XMLHttpRequest events to work around the cross-domain restrictions, you'll want to get back something equivalent to having done the RPC directly yourself. 4. Some transports send live JSON objects, while others send text. In the case of web workers, some (but not all) browsers will automatically parse and instantiate JSON on the receiving end if it's sent in that form, while others will accept the JSON objects and emit them as strings on the receiving end. 5. Some send/receive pairs of channels correlate messages internally, while others have no concept of correlation. In gwt-rpc-plus, correlation is managed internally by each transport, but it would be a lot cleaner if there was something you could layer on top of a send and receive channel that turns it into a bidirectional channel with message correlation. 6. There are some interesting transport concepts that need to be validated against any design. For instance: the W3C's crazy MessageChannel spec requires both a half post-message transport (a sender or receiver to send a port reference) and a sender/receiver pair for the entangled channel. Matt. On 2010-03-22, at 8:42 AM, Joel Webber wrote: [+matt] I can't speak to any experience with either of these libraries, but this also sounds like the work Matt's been doing here: http://code.google.com/p/gwt-rpc-plus/ Can anyone speak to the relationship between these libraries? I'd love to see a standard way of dealing with XDM make it into the GWT core. On Sun, Mar 21, 2010 at 10:59 AM, Sean Kinsey okin...@gmail.com wrote: I've seen many questions on the net on how to enable cross-domain requests with GWT, and most of the solutions I've seen mentioned has been less efficient than what I know the easyXDM library can offer. For those who has never heard of it, easyXDM is a library that conveniently abstracts away all the hassle of hash/fragments, window.name and postMessage, and that exposes a simple and reliable Socket that allows strings to be passed between two documents (no reloads, so both documents can keep state). Whatever kind of transport being used internally (based on what the browser offers etc) the stack will provide _reliability_, queuing (and fragmenting if necessary) and security. Whats interesting with the library is that it also contains an Rpc class, that allows you to invoke methods, with complex arguments (JSON), and with or without return values. From the consumers calling an RPC method is as easy as doing //set up rpc object, only a few simple lines var rpc = new easyXDM.Rpc(... rpc.nameOfMethod(arg1, arg2, arg3, function
Re: [gwt-contrib] IE9 preview support ?
I'm seeing the same thing in our application. I haven't had time to dig into it, but I'm seeing 'unknown event DOMContentLoaded' in the developer tools console. The GWT Showcase example works, however. Maybe some sort of doctype issue? On 2010-03-20, at 4:53 AM, nicolas.deloof wrote: Hi, I tried my GWT 2.0 webapp with the recent test build of IE9 and it doesn't display. I wonder IE9 is not recognized as IE, event whit IE8 mode set. The browser may use a unsuported user-agent ID, is there allready any test done on this new browser ? roadmap to support its better support for standards ? Cheers, Nicolas -- http://groups.google.com/group/Google-Web-Toolkit-Contributors To unsubscribe from this group, send email to google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to this email with the words REMOVE ME as the subject. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors To unsubscribe from this group, send email to google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to this email with the words REMOVE ME as the subject.
Re: [gwt-contrib] deRPC experiences
On 2010-03-18, at 12:15 PM, BobV wrote: - If the GWT module base path URL isn't absolute, getRequestModuleBasePath fails. We use relative base paths to simplify our hosted mode development. Can you describe this setup in more detail? What is the canonical URL that the request's url should be evaluated against? Our setup is pretty complex - we've got our own version of XSLinker that supports development mode, fragments and being embedded inline in the host page. Because we're inlining the selection script, we ripped out the existing code to compute the module base. It was replaced with a single meta tag read by the inlined selection script. At development time, we have a custom servlet filter that generates the host pages dynamically from a set of templates and content files (based on the same code that generates these files statically for deployment to our website). The filter writes out the script to load the selection script dynamically, as well as a header that gets picked up by our custom cross-domain linker. This filter currently writes the base URL relatively, ie: meta name=ds:base content=/com.dotspots.ModuleName/ / I can work around it by picking up the hostname and port from the request in the servlet filter and prefixing the base URL we write with those. I've never had an issue with the relative base URL before and haven't run across code anywhere in the user library that assumes the base URL is absolute. It's pretty simple to fix on our end, however. - WebModePayloadSink seems to throw an NPE when push a null constructorIdent. I'm still digging into this, but it might be related to the fact that we're sending enums with enum value methods across the wire: The code that you posted is about creating a payload for a object that has custom serialization. What does looking at the fields of the InvokeCustomFieldSerializerCommand object show? I don't have an easy way to debug our server against a compiled web mode (we have a launch target for that, but it was so infrequently used that it bitrotted). It might be easier for me to try to reproduce this in a standalone project. I'll give that a shot and report back. RpcServlet is much nicer to work with that RemoveServiceServlet, kudos. It would be nice if the service object (passed into decodeRequest and invokeAndStreamResponse) were retrieved via a protected method, rather than assumed to be 'this'. We wire the service object into the servlet at configuration time via Spring, so I had to duplicate the contents of processCall. How about a protected Object getRequestTargetObject() { return this; } That would be perfect, thanks! Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors To unsubscribe from this group, send email to google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to this email with the words REMOVE ME as the subject.
Re: [gwt-contrib] deRPC experiences
On 2010-03-18, at 12:15 PM, BobV wrote: The code that you posted is about creating a payload for a object that has custom serialization. What does looking at the fields of the InvokeCustomFieldSerializerCommand object show? I can reproduce this in a barebones project. It looks like it's this class we're using to avoid RPC pulling in all the subclasses of HashMap. We have similar classes for ArrayList and HashSet, but those all have custom serializers. I don't know why I didn't create a custom serializer for this class as well (though there aren't any ill effects with standard RPC). public final class RpcMapT, V extends HashMapT, V implements IsSerializable { private static final long serialVersionUID = 0L; public RpcMap() { } public RpcMap(final MapT, V map) { super(map); } public static X, Y RpcMapX, Y wrap(final MapX, Y map) { return map == null ? null : new RpcMapX, Y(map); } } Here are the fields of InvokeCustomFieldSerializerCommand: x InvokeCustomFieldSerializerCommand (id=59) instantiatedTypeClassT (com.dotspots.rpctest.client.RpcMap) (id=102) manuallySerializedType ClassT (java.util.HashMap) (id=107) serializer ClassT (com.google.gwt.user.client.rpc.core.java.util.HashMap_CustomFieldSerializer) (id=108) setters ArrayListE (id=109) values ArrayListE (id=116) Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors To unsubscribe from this group, send email to google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to this email with the words REMOVE ME as the subject.
Re: [gwt-contrib] Re: Avira and HTML/CryptedGen (again)
My previous attempt to submit our code as a false positive disappeared into a black hole. I did get back a note saying it was acknowledged as a false positive and our user reports disappeared for a while. Unfortunately, it looks like they just hacked around the issue - the reports showed up again a few days ago. The original goal was to figure out what in the code was tickling the signature to see if it was RPC-related (which might look malicious to some). When I got the signature down to a handful of byte strings that matched string operations, I just ended up shaking my head. I found a technical support number that I can try calling and seeing if I can get escalated. If that doesn't work, it might be easier to submit a minimal, harmless testcase from those keywords as a false positive. :) Matt. On 2010-03-17, at 8:48 AM, Joel Webber wrote: This is Avira, isn't it? Ddi you ever hear anything back from them about this? It seems like it really ought to be fixed on their end, though I applaud your spelunking for a workaround :) On Tue, Mar 16, 2010 at 3:08 PM, Matt Mastracci matt...@mastracci.com wrote: On Mar 16, 12:42 pm, Matt Mastracci matt...@mastracci.com wrote: Holy cow -- how do they think that is an acceptable measure? Surely they could at least change the warning to say potentially dangerous JS or something rather than declaring it a virus. This probably will likely affect a significant number GWT applications that use RPC. Avira seems to check files ending in .js* and .html* for this pattern. I verified that the scanner intercepts these patterns in HTTP traffic and detects them in IE cache files. There might be some negative patterns as well: Avira doesn't block my message in the Google Groups web interface, but it does block it when viewing the raw message source. Even better: it turns out that if you put the string google anywhere in the file matching CryptedGen, it no longer matches the heuristic. I imagine that it would pick up the string from the class metadata for those not using -XdisableClassMetadata. So this is a virus: for eval .fromcharcode .charcodeat math.min 0,0,0,0,0,0 And this is not: google for eval .fromcharcode .charcodeat math.min 0,0,0,0,0,0 The easiest solution for us seems to be putting the string Google Web Toolkit in a comment in our header. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Re: Avira and HTML/CryptedGen (again)
I found a technical support number that I can try calling and seeing if I can get escalated. If that doesn't work, it might be easier to submit a minimal, harmless testcase from those keywords as a false positive. :) Given their approach, that seems likely to get that exact source added to a whitelist :). That might not be far from the truth. :) I called their tech support line and left a message to be passed on to their technical team, but the tech's solution was you'll have to submit your code again every time it changes. He said he'd pass on the message, but wouldn't guarantee that anyone would contact me with anything more than use the false positive form again. Gah. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Re: Avira and HTML/CryptedGen (again)
On 2010-03-17, at 1:15 PM, John Tamplin wrote: I called their tech support line and left a message to be passed on to their technical team, but the tech's solution was you'll have to submit your code again every time it changes. He said he'd pass on the message, but wouldn't guarantee that anyone would contact me with anything more than use the false positive form again. Gah. Are you a customer or know someone who is? If so, perhaps calling customer support with I am going to stop using this because of bogus false positives would get a better response. Unfortunately not. I first heard about this company's anti-virus through some of our users (who are basically anonymous commenters on our Chrome extension page). I ran the heuristic tests against a trial version that I downloaded. If anyone on this list is an Avira customer and wants to try contacting tech-support to help add some pressure, their USA toll-free number is: +1 888 880 2925. cc'd dflorey, t.broyer and fatompa as three people who mentioned these false positives before and appear to be Avira customers (or know someone who is). Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Avira and HTML/CryptedGen (again)
We started getting reports of the HTML/Crypted.Gen being detected in our Chrome extension again. I've managed to reproduce it - the signature seems to be the exact set of strings they use: .fromCharCode .charCodeAt nodeValue for 0,0,0,0,0,0 Math.min I kid you not - this is their signature for an encrypted JS virus. I can't seem to remove a single character from any of these tokens without turning it from a dangerous virus to a harmless bit of JS. Order doesn't seem to be important (although I haven't experimented with this that much). I think I'll be able to work around this by replacing any sequence of six zeros separated by commas with the sequence 0,0,0,[space]0,0,0. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Avira and HTML/CryptedGen (again)
I kid you not - this is their signature for an encrypted JS virus. I can't seem to remove a single character from any of these tokens without turning it from a dangerous virus to a harmless bit of JS. Order doesn't seem to be important (although I haven't experimented with this that much). I think I'll be able to work around this by replacing any sequence of six zeros separated by commas with the sequence 0,0,0,[space]0,0,0. Holy cow -- how do they think that is an acceptable measure? Surely they could at least change the warning to say potentially dangerous JS or something rather than declaring it a virus. This is pretty unbelievable to me as well. I imagine that the process involved someone finding a mutating JS virus, found six strings that it always contained, put them in and figured that it was safe after surfing around for a bit without any false positives. After experimenting a bit further, I discovered that nodeValue is actually matching case insensitively for eval (which makes a little more sense). This means that the signature is something like for eval .fromcharcode .charcodeat math.min 0,0,0,0,0,0 This probably will likely affect a significant number GWT applications that use RPC. Avira seems to check files ending in .js* and .html* for this pattern. I verified that the scanner intercepts these patterns in HTTP traffic and detects them in IE cache files. There might be some negative patterns as well: Avira doesn't block my message in the Google Groups web interface, but it does block it when viewing the raw message source. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Avira and HTML/CryptedGen (again)
On Mar 16, 12:42 pm, Matt Mastracci matt...@mastracci.com wrote: Holy cow -- how do they think that is an acceptable measure? Surely they could at least change the warning to say potentially dangerous JS or something rather than declaring it a virus. This probably will likely affect a significant number GWT applications that use RPC. Avira seems to check files ending in .js* and .html* for this pattern. I verified that the scanner intercepts these patterns in HTTP traffic and detects them in IE cache files. There might be some negative patterns as well: Avira doesn't block my message in the Google Groups web interface, but it does block it when viewing the raw message source. Even better: it turns out that if you put the string google anywhere in the file matching CryptedGen, it no longer matches the heuristic. I imagine that it would pick up the string from the class metadata for those not using -XdisableClassMetadata. So this is a virus: for eval .fromcharcode .charcodeat math.min 0,0,0,0,0,0 And this is not: google for eval .fromcharcode .charcodeat math.min 0,0,0,0,0,0 The easiest solution for us seems to be putting the string Google Web Toolkit in a comment in our header. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] deRPC experiences
I took the plunge and started moving our codebase over to deRPC. It's pretty simple to get bootstrapped, though there's some deployment work we needed to do to ensure that our .gwt.rpc files are made available to the backends. I'm storing our history of .gwt.rpc files in S3, since we're already pushing files like this into S3 during our deployment. It was trivial to hook up the findClientOracleData to work with the existing process (though we're currently gzipping the already-gzipped policy files): @Override protected InputStream findClientOracleData(String requestModuleBasePath, String permutationStrongName) throws SerializationException { try { return new GZIPInputStream( new URL(http://s3-bucket-name.amazonaws.com/; + permutationStrongName + .gwt.rpc.gz).openStream()); } catch (MalformedURLException e) { throw new SerializationException(e); } catch (IOException e) { throw new SerializationException(e); } } I ran into a few small issues while developing this: - NPE in the WebModeClientOracle.readStreamAsObject finally block if objectInputStream can't be created (ie: if the format is invalid) - If the GWT module base path URL isn't absolute, getRequestModuleBasePath fails. We use relative base paths to simplify our hosted mode development. - WebModePayloadSink seems to throw an NPE when push a null constructorIdent. I'm still digging into this, but it might be related to the fact that we're sending enums with enum value methods across the wire: String constructorIdent = clientOracle.getMethodId(x.getTargetClass(), constructorMethodName, x.getTargetClass()); assert constructorIdent != null : constructorIdent + constructorMethodName; // constructor(new Seed), push(constructorIdent); RpcServlet is much nicer to work with that RemoveServiceServlet, kudos. It would be nice if the service object (passed into decodeRequest and invokeAndStreamResponse) were retrieved via a protected method, rather than assumed to be 'this'. We wire the service object into the servlet at configuration time via Spring, so I had to duplicate the contents of processCall. Overall we saw a small decrease in the initial code fragment (~5%). I didn't notice any particular slowness while testing. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] RFC : Soft permutations for the GWT compiler
On 2010-03-04, at 11:13 AM, BobV wrote: These factory methods need to live in the Java AST so that we can use the type tightener to optimize the (usual-case) polymorphic dispatch. Adding a JHasNameRef node to the AST would allow what you're describing to be built, but I think that would overly complicate the initial implementation. Generally, the result of a GWT.create() is a service implementation assigned to a static field, so the cost of the switch is only paid once. In the case where there's only one answer for a rebound type across the collapsed permutations, such as an async RPC implementation, the GWT.create() is replaced with a plain instantiation expression. Do you have a use case where you're repeatedly calling GWT.create() for instances of a rebound type? We use repeated calls to GWT.create() for dependency injection and to generate code for our internal widget templating framework. Both of them also use nested GWT.create() calls under the hood in generated code for instantiating associated resources bundles. The gwt-rpc-plus framework also uses a call to GWT.create() to initialize the appropriate transports for every request. I can rework them to cache the results of GWT.create(), although I don't believe many of them would ever end up with more than one soft permutation always. The code was written under the assumption that the compiler would elide the call to GWT.create() in most cases and replace instance method calls with static ones (which still holds in most cases of course). It probably won't have a great effect on our overall performance even if some of the classes ended up with runtime switches in the output code, since all of those calls aren't in performance-critical code. Type tightening could still be done ahead of time on the return value of the JSNI method, couldn't it? The results of type tightening would always be the tightest common superclass of all of the potential results. AFAICT, this tightened return value should be statically computable from the list of possible rebinds from the soft permutation since each of the types potentially returned is guaranteed to be in the final output code. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] RFC: sharded linking
On 2010-02-12, at 1:15 PM, Ray Cromwell wrote: On Thu, Feb 11, 2010 at 4:43 PM, Scott Blum sco...@google.com wrote: - I dislike the whole transition period followed by having to forcibly update all linkers, unless there's a really compelling reason to do so. In general, I'd agree, but the number of linkers in the wild appears to be small, this may be a case of trying to preserve an API that only 5 or 10 people in the world are using. +1. I've written a handful of custom linkers (including one in the public gwt-firefox-extension project), but I'm used to updating them between GWT releases to work around subtle changes in the linker contract (ie: the evolution of hosted mode, various global variable changes, etc). I'd rather have a clean linker system that changes from version to version than an awkward one with a lot of legacy interfaces. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Simple, inline actions in UiBinder
Hey all, I've been playing around with UiBinder, hoping to start replacing a lot of our custom templating code with it. One feature that would really improve the experience for our designer/developer interface would be inline actions. A lot of our boilerplate UI event code does one of the of the following: - hides/shows/toggles another element (ie: expando links) - adds/removes/toggers a CSS classname - starts an animation - changes a rollover image It would be really useful if there was a way to plug in actions inline, something like the following pseudo-gwtquery code: span class=actionLearnMore a title=Learn more about dots ui:click='${infoBox}.as(Effects).slideToggle()'Learn more/a div id=infoBox More info... /div /span I don't know what the ideal syntax would look like, but even something trivial would be able to replace 99% of the UI event code we have to write. Thoughts? Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Simple, inline actions in UiBinder
That custom parser would be great for now, thanks for the ideas. My understanding of UiBinder is woefully incomplete right now, so I'll need to dig into it a bit more to see how to do this. Thanks, Matt. On 2010-01-05, at 1:52 PM, Ray Cromwell wrote: Great idea, I was thinking of having something like ui:query/ui:query and use $(id) to wire up stuff, but this is even better since you avoid the lazy() or anonymous inner class. The alternative is to have a custom parser like gq:query $(.actionLearnMore a).click(lazy().as(Effects).slideToggle().end()); /gq:query This could be simplified further for callback actions: gq:click query=.actionLearnMore a as(Effects().slideToggle(); /gq:action -Ray On Tue, Jan 5, 2010 at 12:42 PM, Matt Mastracci matt...@mastracci.com wrote: Hey all, I've been playing around with UiBinder, hoping to start replacing a lot of our custom templating code with it. One feature that would really improve the experience for our designer/developer interface would be inline actions. A lot of our boilerplate UI event code does one of the of the following: - hides/shows/toggles another element (ie: expando links) - adds/removes/toggers a CSS classname - starts an animation - changes a rollover image It would be really useful if there was a way to plug in actions inline, something like the following pseudo-gwtquery code: span class=actionLearnMore a title=Learn more about dots ui:click='${infoBox}.as(Effects).slideToggle()'Learn more/a div id=infoBox More info... /div /span I don't know what the ideal syntax would look like, but even something trivial would be able to replace 99% of the UI event code we have to write. Thoughts? Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Simple, inline actions in UiBinder
Definitely agree with that statement: JSP files with entire blocks of Java code are usually an unreadable mess. All of the use-cases I could name are simple lists of actions that happen on elements somewhere within the current control. Some of the actions are more complex, such as GWTQuery-style transitions that require asynchronous callbacks, while others are synchronous CSS style or attribute changes. All of them are triggered by DOM events of some sort: click, mouseover, mouseout, focus, blur. The idea is to allow the large subset of basic functionality to be added at design time without involving developers in any way. I imagine a set of bindings for some basic events, plus a way to add bindings for other transitions specified elsewhere. I'm not proposing a syntax here, just an illustration of the level of control I'd imagine a designer to have: span ui:mouseover=gq:slideDown(answer, 10); ui:addClass({style.blink}); ui:mouseout=gq:slideUp(answer, 10);Peek at the answer/span div id=answer 42 /div Matt. On 2010-01-05, at 2:13 PM, Joel Webber wrote: I've generally been somewhat opposed to the idea of little languages creeping into UiBinder code, because it's much harder to provide tools to help with the code. But I can also see the utility of something like this. If we're to address this problem, we should do some thinking about how best to provide a sensible set of restrictions (i.e. not all of Java) that encourage people to do more complex things in normal Java code. We should also be thinking about how best to make this work with whatever binding framework we decide to use. On Tue, Jan 5, 2010 at 3:52 PM, Ray Cromwell cromwell...@gmail.com wrote: Great idea, I was thinking of having something like ui:query/ui:query and use $(id) to wire up stuff, but this is even better since you avoid the lazy() or anonymous inner class. The alternative is to have a custom parser like gq:query $(.actionLearnMore a).click(lazy().as(Effects).slideToggle().end()); /gq:query This could be simplified further for callback actions: gq:click query=.actionLearnMore a as(Effects().slideToggle(); /gq:action -Ray On Tue, Jan 5, 2010 at 12:42 PM, Matt Mastracci matt...@mastracci.com wrote: Hey all, I've been playing around with UiBinder, hoping to start replacing a lot of our custom templating code with it. One feature that would really improve the experience for our designer/developer interface would be inline actions. A lot of our boilerplate UI event code does one of the of the following: - hides/shows/toggles another element (ie: expando links) - adds/removes/toggers a CSS classname - starts an animation - changes a rollover image It would be really useful if there was a way to plug in actions inline, something like the following pseudo-gwtquery code: span class=actionLearnMore a title=Learn more about dots ui:click='${infoBox}.as(Effects).slideToggle()'Learn more/a div id=infoBox More info... /div /span I don't know what the ideal syntax would look like, but even something trivial would be able to replace 99% of the UI event code we have to write. Thoughts? Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Inlining nocache.js
If it's the same error we ran into, it's that there are things that look like HTML script and comment tags in the linker script that throw the parser off. Note how we broke up the script start tags and comment start/end tags the same way as the script end tags: XSLinker: var compiledScriptTag = 'script src=\\' + base + strongName + '.cache.js\\/scr + ipt'; $doc.write('script!--\n' + 'window.__gwtStatsEvent window.__gwtStatsEvent({' + 'moduleName:__MODULE_NAME__, sessionId:$sessionId, subSystem:startup,' + 'evtGroup: loadExternalRefs, millis:(new Date()).getTime(),' + 'type: end});' + 'window.__gwtStatsEvent window.__gwtStatsEvent({' + 'moduleName:__MODULE_NAME__, sessionId:$sessionId, subSystem:startup,' + 'evtGroup: moduleStartup, millis:(new Date()).getTime(),' + 'type: moduleRequested});' + 'document.write(' + compiledScriptTag + ');' + '\n--/script'); Our linker: var compiledScriptTag = 'scr'+'ipt src=\\' + base + strongName + '\\/scr + ipt'; $doc.write('scr'+'ipt!-'+'-\n' + 'window.__gwtStatsEvent window.__gwtStatsEvent({' + 'moduleName:__MODULE_NAME__, subSystem:startup,' + 'evtGroup: loadExternalRefs, millis:(new Date()).getTime(),' + 'type: end});' + 'window.__gwtStatsEvent window.__gwtStatsEvent({' + 'moduleName:__MODULE_NAME__, subSystem:startup,' + 'evtGroup: moduleStartup, millis:(new Date()).getTime(),' + 'type: moduleRequested});' + 'document.write(' + compiledScriptTag + ');' + '\n-'+'-/scr'+'ipt'); We've had inlining working on dotspots.com in GWT trunk for a while now, but I'm considering going back to an external nocache.js so we can more easily decouple our static content from the GWT code. Matt. On 2009-12-17, at 12:40 PM, George Georgovassilis wrote: Some time ago we discussed [1] inlining nocache.js into the host page to speed up initial page load, which I find quite worthwhile a read. While back in the 1.7 days I managed to inline nochache.js with a modest effort of post processing (escaping some javascript), 2.0 defeats me. I can't find a way to inline the GWT 2.0 compiler's nocache.js into the host page without always running into some javascript syntax error, which prohibits the entire code from loading. Any hints? [1] http://groups.google.com/group/google-web-toolkit-contributors/browse_thread/thread/8127c586073b1711/2eeb884f6f5cdcbf?lnk=gstq=inline#2eeb884f6f5cdcbf -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] now.. afetr GWT 2.0?
GWT 2.0 was so awesome, it'll be hard to top any of the new stuff with my feature wishlist. A few things I'd like: - moving as many compiler properties as possible into configuration properties so we can build an instrumented release (with type cast checking, assertions, emulated stack traces) at the same time as release that can be turned on via - A DOM object to represent the window - Less of a hit on first load in development mode - New linker that uses iframes with dynamic scripts and a more generic, more easily reusable hosted mode script Matt. On 2009-12-16, at 10:01 AM, Bruce Johnson wrote: Working on a draft one. What do folks here think is important? On Wed, Dec 16, 2009 at 7:42 AM, tfreitas tfrei...@gmail.com wrote: What about roadmap? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Revisiting the script-via-iframe default linkage
On 15-Dec-09, at 12:48 PM, Lex Spoon wrote: I've now double checked on several browsers other than Opera, and I agree that onerror works on non-IE and onreadystatechange works on IE. Details here: http://blog.lexspoon.org/2009/12/detecting-download-failures-with-script.html One tricky aspect is that I don't see how to get IE to say whether or not the download really failed. Sometimes the loaded state is reached when loading a page that is not in cache. I just ran some further tests - it looks like 'complete' is always fired while cached, 'loaded' always when not cached (and always after a loading event). Note that it will also fire 'interactive' sometimes if you use alert() from the script, or if the 'error on page' dialog pops up. I can't quite pin down the circumstances in which this readystate chooses to fire. I whipped up a slightly improved test based on your post that logs the order of events here: http://grack.com/errortest.html For all of the cached/uncached runs I did on IE6, IE7 and IE8 the script was always evaluated before complete or loaded was fired. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Re: Avira is showing warning when accessing gwt-generated files
I got a report of a user seeing the same signature on our website. I've got a second submission in the queue to cover that one as well. They've got a testing license that I should be able to download and use to reduce when I have a second. On 2009-12-09, at 11:29 AM, Joel Webber j...@google.com wrote: Were you able to get any information on the signature (assuming it's signature-based) from Avira? Their page on the subject is, uh, less than useful. On Wed, Dec 9, 2009 at 1:09 PM, Matt Mastracci matt...@mastracci.com wrote: We've just had reports of people seeing this while installing our chrome extension. I'm not near a Windows VM right now, but I can see if it's easy to reproduce when I get back: http://getsatisfaction.com/dotspots/topics/dotspots_plugin_for_chrome_installer_problems There's a lot of embedded CSS in the script, as well as HTML snippets. It's the same virus report as Daniel earlier: HTML/Crypted.Gen. Matt. On 30-Nov-09, at 9:20 AM, Joel Webber wrote: If you can find out what was triggering this from Avira, I'd really like to see it. This is probably the third-ish time we've seen a report like this, and it would be really helpful to understand what kind of virus snippets they're looking for. If there's something we can do in our code gen to avoid the problem in the future, it would probably be worth it. On Mon, Nov 30, 2009 at 10:19 AM, Thomas Broyer t.bro...@gmail.com wrote: On Nov 30, 3:43 pm, BobV b...@google.com wrote: On Sat, Nov 28, 2009 at 10:54 AM, Ray Ryan rj...@google.com wrote: Does one app make heavier use of CssResource than the other? A bell is ringing about mhtml security concerns. Or did we back out our mhtml use? I disabled MHTML support in r6839 (trunk) and r6840 (2.0) because it has too many browser/OS gotchas to be reliable for the 2.0 release. And it couldn't have been MHTML in our case, as we're serving the app with HTTPS, which is sniffed in MhtmlClientBundleGenerator to fall back to a one file/request per resource (otherwise, the mhtml: pseudo-protocol causes a mixed content warning in IE). -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Re: Avira is showing warning when accessing gwt-generated files
We've just had reports of people seeing this while installing our chrome extension. I'm not near a Windows VM right now, but I can see if it's easy to reproduce when I get back: http://getsatisfaction.com/dotspots/topics/dotspots_plugin_for_chrome_installer_problems There's a lot of embedded CSS in the script, as well as HTML snippets. It's the same virus report as Daniel earlier: HTML/Crypted.Gen. Matt. On 30-Nov-09, at 9:20 AM, Joel Webber wrote: If you can find out what was triggering this from Avira, I'd really like to see it. This is probably the third-ish time we've seen a report like this, and it would be really helpful to understand what kind of virus snippets they're looking for. If there's something we can do in our code gen to avoid the problem in the future, it would probably be worth it. On Mon, Nov 30, 2009 at 10:19 AM, Thomas Broyer t.bro...@gmail.com wrote: On Nov 30, 3:43 pm, BobV b...@google.com wrote: On Sat, Nov 28, 2009 at 10:54 AM, Ray Ryan rj...@google.com wrote: Does one app make heavier use of CssResource than the other? A bell is ringing about mhtml security concerns. Or did we back out our mhtml use? I disabled MHTML support in r6839 (trunk) and r6840 (2.0) because it has too many browser/OS gotchas to be reliable for the 2.0 release. And it couldn't have been MHTML in our case, as we're serving the app with HTTPS, which is sniffed in MhtmlClientBundleGenerator to fall back to a one file/request per resource (otherwise, the mhtml: pseudo-protocol causes a mixed content warning in IE). -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Re: Avira is showing warning when accessing gwt-generated files
I just submitted the samples a short while ago. The status is currently Our Virus Research Team still works on your submission. The automated system gave me these URLs to follow the progress of the submission. I hope something useful will show up here when they are processed: http://analysis.avira.com/samples/details.php?uniqueid=B8Q5Urw04jQTrwPBhzSHkqBxYqh48wjzincidentid=408384 http://analysis.avira.com/samples/details.php?uniqueid=B8Q5Urw04jQTrwPBhzSHkqBxYqh48wjz On 9-Dec-09, at 10:29 AM, Joel Webber wrote: Were you able to get any information on the signature (assuming it's signature-based) from Avira? Their page on the subject is, uh, less than useful. On Wed, Dec 9, 2009 at 1:09 PM, Matt Mastracci matt...@mastracci.com wrote: We've just had reports of people seeing this while installing our chrome extension. I'm not near a Windows VM right now, but I can see if it's easy to reproduce when I get back: http://getsatisfaction.com/dotspots/topics/dotspots_plugin_for_chrome_installer_problems There's a lot of embedded CSS in the script, as well as HTML snippets. It's the same virus report as Daniel earlier: HTML/Crypted.Gen. Matt. On 30-Nov-09, at 9:20 AM, Joel Webber wrote: If you can find out what was triggering this from Avira, I'd really like to see it. This is probably the third-ish time we've seen a report like this, and it would be really helpful to understand what kind of virus snippets they're looking for. If there's something we can do in our code gen to avoid the problem in the future, it would probably be worth it. On Mon, Nov 30, 2009 at 10:19 AM, Thomas Broyer t.bro...@gmail.com wrote: On Nov 30, 3:43 pm, BobV b...@google.com wrote: On Sat, Nov 28, 2009 at 10:54 AM, Ray Ryan rj...@google.com wrote: Does one app make heavier use of CssResource than the other? A bell is ringing about mhtml security concerns. Or did we back out our mhtml use? I disabled MHTML support in r6839 (trunk) and r6840 (2.0) because it has too many browser/OS gotchas to be reliable for the 2.0 release. And it couldn't have been MHTML in our case, as we're serving the app with HTTPS, which is sniffed in MhtmlClientBundleGenerator to fall back to a one file/request per resource (otherwise, the mhtml: pseudo-protocol causes a mixed content warning in IE). -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Revisiting the script-via-iframe default linkage
On 9-Dec-09, at 1:55 PM, Lex Spoon wrote: On Wed, Dec 9, 2009 at 12:47 PM, Matt Mastracci matt...@mastracci.com wrote: Do you know how to get onerror to fire in IE? It didn't seem to work in my testing. No, but why do you need it if you have onreadystatechanged? It should be no problem to hook up both callbacks. Yeah, you don't need the onerror stuff in the end - everything can be done via onload and onreadystatechange. I was hoping that one of the browsers would justify adding onerror to the mix by providing some additional information on why the script failed to load, but there's nothing useful in any of the errors that I've seen. Setting up both onload and onreadystatechanged, directly assigned to the properties on the script element's DOM object seems to be the way to go. It covers both the success and error cases and works on everything but Opera. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Strange JSNI timing errors in WebKit dev mode
I'm seeing a strange dev mode error in WebKit. It started happening recently and I can't put my finger on a specific change that would cause it. I'm returning an non-null JS native array from a JSNI method, cast to JsArrayInteger. When I call JsArrayInteger::shift() on it, I get: Result of expression 'this.shift' [undefined] is not a function. If I defer this operation with the scheduler after catching the exception (or step through with the debugger), it works as expected. It appears to be a race of some sort but I'm not really sure what it could be. Everything else is working as it should. Safari breaks on an exception in that method, but the console shows a valid value for 'this' and 'this.shift'. The same code runs successfully a number of times before it fails and all of the arrays (successful or not) are part of the same large data structure. Any ideas? Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Revisiting the script-via-iframe default linkage
Ray/Lex, I'm starting to think that the dynamic iframe might not be a bad first approach to this problem either. A single linker would be able to provide cross-domain-capable, multi-module-safe code that doesn't require any additional post-processing to support loading of fragments. It also runs in the global scope, saving the extra few ms per global access (http://blog.j15r.com/2009/08/where-should-i-define-javascript.html ). The method used to load the first and additional fragments could become a linker property. For our cross-domain loads, I'd like to have a strategy that tries to use cross-domain XMLHttpRequest first, assuming appropriate Access-Control-* headers on the other end, then falls back to script tags if this isn't available. The default could be something simple like script tags, or even standard XMLHttpRequest, assuming the auxiliary scripts are stored on the same domain. It still has the disadvantage of being slightly more magical, requiring tricks to work around IE's window event security, but the advantages are pretty substantial. It should be possible to write this linker as a drop-in replacement for today's XSLinker and IFrameLinkers without touching any code outside of com.google.gwt.core.linker. Matt. On 30-Nov-09, at 5:09 PM, Ray Cromwell wrote: Lex, JSONP loading + dynamic iframe seems like a straightforward viable option that doesn't require a lot of complicated compiler work, what do you think of providing this as an option? -Ray On Mon, Nov 30, 2009 at 12:29 PM, Lex Spoon sp...@google.com wrote: (Reposting to get it on the mailing list; first try bounced.) Hey, Matt, I agree with your analysis about the code-splitting issues. I've worked out a preliminary patch to do var renaming, but I haven't shared it yet because it's in a pretty early state. I could share it if you or someone is eager enough to see it that you're willing to hack some code to get to use it. To really get it polished up into a committable state, the main issue will be figuring out when to enable the rewrites.Whether to enable it or not depends on the choice of linker. For the off-domain loading, I was thinking to look into a JSONP-like downloader. That, too, is something that should only optionally be enabled, because it has worse download failure reporting. Thus, again the hardest part will be figuring out when to enable it. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] GPE 2.0-RC2 and GWTShell
Hey all, I installed the GPE 2.0-RC2 build (after cleaning out the old one) and I'm running into some issues. The plugin thinks that we're using the old-style layout, so it's attempting to launch GWTShell which won't initialize a local Jetty w/war.xml. I've worked around it by creating a local copy of GWTShell that delegates to DevMode, but I'd like to figure out why it's using the wrong launch target. What is the heuristic for determining whether a project uses the war layout vs. the GWTShell layout? Thanks, Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] GPE 2.0-RC2 and GWTShell
Ahh - there's a webAppNature in .project that gets set when you enable GWT. I disabled GWT support, re-added it and now the .project has a com.google.gdt.eclipse.core.webAppNature. This seems to be the trigger for enabling DevMode vs. GWTShell. Thanks, Matt. On 1-Dec-09, at 1:57 PM, Joel Webber wrote: @Miguel: I've hit this before when upgrading projects, and I keep forgetting what the trick was. I seem to recall the plugin was making the project layout determination at the time the GWT nature is added, but I'm not 100% certain. On Tue, Dec 1, 2009 at 3:55 PM, Matt Mastracci matt...@mastracci.com wrote: Hey all, I installed the GPE 2.0-RC2 build (after cleaning out the old one) and I'm running into some issues. The plugin thinks that we're using the old-style layout, so it's attempting to launch GWTShell which won't initialize a local Jetty w/war.xml. I've worked around it by creating a local copy of GWTShell that delegates to DevMode, but I'd like to figure out why it's using the wrong launch target. What is the heuristic for determining whether a project uses the war layout vs. the GWTShell layout? Thanks, Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Revisiting the script-via-iframe default linkage
Sure, I'd love to take a look at it. I've got a basic version of globally-scoped, cross-domain code-splitting up and running that uses simple script-tags for the cross-domain load right now. Re: script tag error reporting. In my investigations, this has been particularly bad and highly variable across browsers. I came away with three conclusions: 1. onload or onreadystatechange works across all browsers to detect a successful load, but it's moot because you can use JSONP callbacks to do this. 2. onerror works some of the time in some of the browsers. It fails on various combinations of resolve errors, error status codes and other failure conditions. For all browsers (except Opera) that don't support it directly, It can be emulated with onreadystatechange/onload and lack of a JSONP callback. 3. Opera can't detect that a script failed to load in any way that I've found: none of window.onerror, script.onerror, script.onreadystatechange will fire when the script fails to load. Matt. On 30-Nov-09, at 1:27 PM, Lex Spoon wrote: Hey, Matt, I agree with your analysis about the code-splitting issues. I've worked out a preliminary patch to do var renaming, but I haven't shared it yet because it's in a pretty early state. I could share it if you or someone is eager enough to see it that you're willing to hack some code to get to use it. To really get it polished up into a committable state, the main issue will be figuring out when to enable the rewrites.Whether to enable it or not depends on the choice of linker. For the off-domain loading, I was thinking to look into a JSONP-like downloader. That, too, is something that should only optionally be enabled, because it has worse download failure reporting. Thus, again the hardest part will be figuring out when to enable it. Lex -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Revisiting the script-via-iframe default linkage
I put some thought into this last night and there are some interesting questions raised: By default, the IFrameLinker allows multiple modules to coexist on the same page. To replicate this with scripts, you need to ensure that all scripts are privately scoped. There are conflicts with privately- scoped scripts and dynamically-loaded code. You can mutate the global scope of a window, but I don't know of any way to add new identifiers to the scope of a function used as a private namespace after that function has terminated. It is possible to evaluate code within an existing private scope. As long as you can structure the symbol dependencies between runAsync modules such that it can be represented as a DAG, two fragments never providing visible identifiers for each other, you can load the various modules as a tree of scopes. I'm not deeply familiar with runAsync, so I don't know if it is always true. The worst-case end-result of loading 10 different fragments, each depending on symbols from the last n-1 loaded fragments would effectively be the equivalent of 10- deep nested scope chain. I don't know what effect this would have on performance. Here's a summary of the linking options that I know of. I've added in an alternative iframe linker that doesn't load HTML from a remote source, but dynamically constructs the iframe contents and injects the scripts into it: 1. Monolithic iframe (IFrameLinker): Supports multimodule: Yes Supports off-domain loading: No Supports runAsync: Yes Global namespace pollution: Only within the iframe 2. Dynamic iframe, injected with scripts, ie: create iframes dynamically with src=javascript:; and document.write()ing an HTML document: Supports multimodule: Yes Supports off-domain loading: Yes Supports runAsync: Yes Global namespace pollution: Only within the iframe 3. Globally-scoped script: Supports multimodule: No Supports off-domain loading: Yes Supports runAsync: Yes Global namespace pollution: Yes 4. Privately-scoped script (XSLinker): Supports multimodule: Yes Supports off-domain loading: Yes Supports runAsync: Possibly, but with potential size/speed consequences Global namespace pollution: None Matt. On 25-Nov-09, at 12:39 AM, Ray Cromwell wrote: err, not explicit scope, I mean predeclare all your symbols with 'var' privarte scope. -Ray On Tue, Nov 24, 2009 at 11:29 PM, Ray Cromwell cromwell...@gmail.com wrote: IMHO, pollution of the global namespace is a big problem for general purpose apps. It's ok to do it when you control everything (e.g. Wave), but probably a bad idea for enterprise users who have a habit of composing lots of small GWT modules on a single dashboard. We probably need to support both explicit scope and polluting options, and allow the developer to choose. -Ray On Tue, Nov 24, 2009 at 8:33 PM, Scott Blum sco...@google.com wrote: On Tue, Nov 24, 2009 at 9:39 PM, Matt Mastracci matt...@mastracci.com wrote: Hey Scott, I've ported hosted.html over to hosted.js a few times and it's not actually a problem. The only significant differences between the two files are s/parent/window/ and how you pass the name of the module to the hosted-mode bootstrap script. Each version of the plugin tested (Safari, FF and IE from a few months ago and recent Safari/FF builds) has been able to work in this environment without modification. I don't think the hosted-mode plugin would work with the privately- scoped XSLinker today, but it definitely works with our modified version that links the JS at the global scope. Okay, that makes sense to me. I think to really ship this, though, we want the plugins to put their symbols into a private namespace. Otherwise two modules on one page would step all over each other, for example. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Re: Avira is showing warning when accessing gwt-generated files
The best approach is probably to upload the file in question to Avira's false-positive reporting page: http://analysis.avira.com/samples/index.php On 24-Nov-09, at 8:19 AM, dflorey wrote: Am I the only one with this issue? On 19 Nov., 17:29, dflorey daniel.flo...@gmail.com wrote: Hi, since a few weeksAviraAntiVir is generating warnings when accessing gwt-generated files: When accessing data from the URL, http:// allcontacts.southpolecarbon.com/sharedcontacts/ C7C22E75261E4D2C9C7FAF82B71C40B0.cache.html a virus or unwanted program 'HTML/Crypted.Gen' [virus] was found. Action taken: Ignored Any ideas how to get rid of these warnings? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Revisiting the script-via-iframe default linkage
Hey all, If I recall correctly, the original reason that GWT used iframe- wrapped scripts was to work around the buggy compression of Javascript some early versions of IE (example: http://support.microsoft.com/default.aspx?scid=kb;en-us;823386Product=ie600) . The number of users on IE 6 SP1 is likely fairly small right now and at some point, IE6 is going to drop off the map entirely. I wonder if it might be a good time for GWT to consider the switch to raw JS files and consider IE6 SP1 as a special case to work around. There's a number of advantages to serving raw JS: - You can serve it from a CDN (we do this right now, but it requires a lot of work on our side to track the hosted mode code) - It doesn't require an additional browser rendering context - XSLinker is no longer a special case: wrapping the code in a closure to prevent namespace pollution can be a configuration property - Better guarantees on parallel downloads for loading leftover and exclusive fragments simultaneously - Window events no longer need selection-script support to be hooked up (to work around the IE security bugs) - Less magical overall: a design closer to that of other modular JS toolkits It seems like the post-2.0 GWT codebase would be a reasonable time to proceed along this path. I've been using this approach for some time and it's been working very well. Thoughts? Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] TypeOracle allTypes including types not in a source path
I'm getting closer to figuring out exactly what happened here. The extra classes that were getting included were all under root-package/ client. I've restructured our half-dozen GWT modules so that they all inherit source paths and imports from a basic set of root modules. For modules that differ only in entry point, the module XML looks something like this: module inherits name='rootpackage.Common' / entry-point class='rootpackage.othermodule.Module' / /module When GWT loads a module without any source elements in a module, it adds an implicit source path=client / in ModuleDefSchema. After some module refactoring that took place in my GWT 2.0 porting work, the modules that no longer had source paths after I had modified the modules were causing extra source to be silently imported: (from ModuleDefSchema): // Maybe infer source and public. // if (!foundExplicitSourceOrSuperSource) { bodySchema.addSourcePackage(modulePackageAsPath, client, Empty.STRINGS, Empty.STRINGS, true, true, false); } I can no longer reproduce the specific crash below, but I strongly suspect it was related to the other compiler errors. I'll work around the implicit source path issue for now by using fake source paths in modules that don't have any additional source imports. If possible, it would be useful if there were a log warning explaining that the source path is defaulting to client. After fixing this, I managed to get my first GWT 2.0 build working from the command line with a free 4% savings on final code size. :) Thanks, Matt. On 20-Nov-09, at 11:05 AM, Scott Blum wrote: Hi Matt, I need more information, because on the face of it, I don't see how we can be pulling in all types in all cases. We have specific type oracle tests that check how many types total end up in type oracle. If it was a fundamental problem, these tests should be blowing up. Example: http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/test/com/google/gwt/dev/javac/TypeOracleMediatorTest.java#1060 So, I stuck added the following code at the end of TypeOracleMediator.addNewUnits() and compiled the Hello sample: StringBuilder sb = new StringBuilder(); for (JClassType type : typeOracle.getTypes()) { String sn = type.getQualifiedSourceName(); if (sn.contains(.client.)) { continue; } if (sn.contains(.shared.)) { continue; } if (sn.startsWith(java.)) { continue; } if (sn.startsWith(com.google.gwt.lang.)) { continue; } sb.append(sn); sb.append('\n'); } PerfLogger.end(); breakpoint here I didn't see anything get added that shouldn't be there. Can you dig into this a little or put together a small sample? Thanks, Scott On Thu, Nov 19, 2009 at 10:40 PM, Matt Mastracci matt...@mastracci.com wrote: Hey all, Sorry to keep spamming GWT 2.0 issues. I've run into a difference in how TypeOracle works that seems to have changed in GWT 2.0. In previous versions, calling context.getTypeOracle().getTypes() from a generator would limit itself to types available on the source paths. I have some code that took advantage of that to build a quick-and-dirty annotation-based dependency-injection framework. It generates a single factory class which contains methods to initialize all of the injectable classes (and injectee) classes available on the source path. It seems that getTypeOracle().getTypes() is now returning all classes available on the classpath, rather than limiting itself to source- specified classes. These classes are picked up by the factory and generated into the new class, which then ends up causing a java.lang.NoClassDefFoundError when this class is instantiated: Caused by: java.lang.NoClassDefFoundError: XXX at java.lang.Class.getDeclaredConstructors0(Native Method) at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357) at java.lang.Class.getDeclaredConstructors(Class.java:1808) at com .google .gwt .dev .shell .DispatchClassInfo .lazyInitTargetMembersUsingReflectionHelper(DispatchClassInfo.java: 163) at com .google .gwt .dev .shell.DispatchClassInfo.lazyInitTargetMembers(DispatchClassInfo.java: 146) at com .google .gwt.dev.shell.DispatchClassInfo.getMemberId(DispatchClassInfo.java: 55) at com.google.gwt.dev.shell.CompilingClassLoader $DispatchClassInfoOracle.getDispId(CompilingClassLoader.java:166) at com .google .gwt .dev.shell.CompilingClassLoader.getDispId(CompilingClassLoader.java: 930) at com.google.gwt.dev.shell.Jsni $JsSourceGenWithJsniIdentFixup.visit(Jsni.java:105) The exception itself is probably a bug (not sure why it didn't trigger a compiler error), but I'm not sure if TypeOracle.getTypes() returning all types is by design. I've been looking for an excuse to ditch the custom IoC code
Re: [gwt-contrib] TypeOracle allTypes including types not in a source path
Filed a bug on this: http://code.google.com/p/google-web-toolkit/issues/detail?id=4268 On 23-Nov-09, at 12:40 PM, Bruce Johnson wrote: let's remember to talk about this more for the release after 2.0 On Mon, Nov 23, 2009 at 2:26 PM, Isaac Truett itru...@gmail.com wrote: +1 deprecate and warn. On Mon, Nov 23, 2009 at 2:24 PM, Ray Ryan rj...@google.com wrote: FWIW, this confusion is exactly why webAppCreator no longer generates projects that use the implicit include. I wonder if we shouldn't flat out deprecate it--in which case a warning would be the right thing. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] TypeOracle allTypes including types not in a source path
I can't repro this on a smaller scale. I created small project with two modules and TypeOracle was populated correctly (GWT 2.0-RC1 and trunk), even when compiling both modules together or running DevMode with both modules specified. I'll keep trying to reproduce this, sorry for the false alarm. Matt. On 20-Nov-09, at 11:05 AM, Scott Blum wrote: Hi Matt, I need more information, because on the face of it, I don't see how we can be pulling in all types in all cases. We have specific type oracle tests that check how many types total end up in type oracle. If it was a fundamental problem, these tests should be blowing up. Example: http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/test/com/google/gwt/dev/javac/TypeOracleMediatorTest.java#1060 So, I stuck added the following code at the end of TypeOracleMediator.addNewUnits() and compiled the Hello sample: StringBuilder sb = new StringBuilder(); for (JClassType type : typeOracle.getTypes()) { String sn = type.getQualifiedSourceName(); if (sn.contains(.client.)) { continue; } if (sn.contains(.shared.)) { continue; } if (sn.startsWith(java.)) { continue; } if (sn.startsWith(com.google.gwt.lang.)) { continue; } sb.append(sn); sb.append('\n'); } PerfLogger.end(); breakpoint here I didn't see anything get added that shouldn't be there. Can you dig into this a little or put together a small sample? Thanks, Scott On Thu, Nov 19, 2009 at 10:40 PM, Matt Mastracci matt...@mastracci.com wrote: Hey all, Sorry to keep spamming GWT 2.0 issues. I've run into a difference in how TypeOracle works that seems to have changed in GWT 2.0. In previous versions, calling context.getTypeOracle().getTypes() from a generator would limit itself to types available on the source paths. I have some code that took advantage of that to build a quick-and-dirty annotation-based dependency-injection framework. It generates a single factory class which contains methods to initialize all of the injectable classes (and injectee) classes available on the source path. It seems that getTypeOracle().getTypes() is now returning all classes available on the classpath, rather than limiting itself to source- specified classes. These classes are picked up by the factory and generated into the new class, which then ends up causing a java.lang.NoClassDefFoundError when this class is instantiated: Caused by: java.lang.NoClassDefFoundError: XXX at java.lang.Class.getDeclaredConstructors0(Native Method) at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357) at java.lang.Class.getDeclaredConstructors(Class.java:1808) at com .google .gwt .dev .shell .DispatchClassInfo .lazyInitTargetMembersUsingReflectionHelper(DispatchClassInfo.java: 163) at com .google .gwt .dev .shell.DispatchClassInfo.lazyInitTargetMembers(DispatchClassInfo.java: 146) at com .google .gwt.dev.shell.DispatchClassInfo.getMemberId(DispatchClassInfo.java: 55) at com.google.gwt.dev.shell.CompilingClassLoader $DispatchClassInfoOracle.getDispId(CompilingClassLoader.java:166) at com .google .gwt .dev.shell.CompilingClassLoader.getDispId(CompilingClassLoader.java: 930) at com.google.gwt.dev.shell.Jsni $JsSourceGenWithJsniIdentFixup.visit(Jsni.java:105) The exception itself is probably a bug (not sure why it didn't trigger a compiler error), but I'm not sure if TypeOracle.getTypes() returning all types is by design. I've been looking for an excuse to ditch the custom IoC code for Guice- GWT, however. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] NPE in JsniChecker in 2.0-RC1
Thanks, Scott. I'm applying it now and building GWT. It's been catching some JSNI refs in the GWT source, possibly some false- positive (the JSONParser ones seem to be valid?). The build doesn't actually fail, though: [java] [WARN] Warnings in 'jar:file:/Users/matthew/ Documents/dotspots/gwt/trunk-clean/build/lib/gwt-user.jar!/com/google/ gwt/emul/java/util/AbstractHashMap.java' [java] [WARN] Line 293: Referencing method 'java.util.AbstractHashMap$MapEntryString.new(Ljava/util/ AbstractHashMap;Ljava/lang/String;)': unable to resolve method, expect subsequent failures [java] [WARN] Line 432: Referencing method 'java.util.MapEntryImpl.new(Ljava/lang/Object;Ljava/lang/Object;)': unable to resolve method, expect subsequent failures [java] [WARN] Warnings in 'jar:file:/Users/matthew/ Documents/dotspots/gwt/trunk-clean/build/lib/gwt-user.jar!/com/google/ gwt/layout/client/LayoutImplIE6.java' [java] [WARN] Line 338: Referencing method 'com.google.gwt.layout.client.Layout.Alignment.ordinal()': unable to resolve method, expect subsequent failures [java] [WARN] Line 340: Referencing method 'com.google.gwt.layout.client.Layout.Alignment.ordinal()': unable to resolve method, expect subsequent failures [java] [WARN] Warnings in 'jar:file:/Users/matthew/ Documents/dotspots/gwt/trunk-clean/build/lib/gwt-user.jar!/com/google/ gwt/json/client/JSONParser.java' [java] [WARN] Line 98: Referencing method 'com.google.gwt.json.client.JSONArray.new(Lcom/google/gwt/core/client/ JavaScriptObject;)': unable to resolve method, expect subsequent failures [java] [WARN] Line 102: Referencing method 'com.google.gwt.json.client.JSONObject.new(Lcom/google/gwt/core/client/ JavaScriptObject;)': unable to resolve method, expect subsequent failures On 19-Nov-09, at 9:18 AM, Scott Blum wrote: @Matt: IIRC you are hittnig this because you have a parse error in one of your JSNI methods. Either apply my patch and try it again, or else binary search for the offending method by commenting hafl of them out at a time. The good news is the error will likely repro in hosted mode, so it shouldn't take too long. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] OOPHM crashes in FF 3.5
Hey all, I'm continuing my push forward to GWT 2.0-RC1 and I'm running into some crashiness in OOPHM. I'm still trying to narrow down exactly what causes it, but this is a common, reproducible crash that I'm seeing: http://crash-stats.mozilla.com/report/index/bp-4526a9fc-7ff1-4910-8998-df6432091119 http://crash-stats.mozilla.com/report/index/90c433b3-c724-4148-ad52-642fa2091119 It seems to crash immediately after a message like this on the console: Missing jsObject with id 5704 I'm also occasionally seeing the following crash on shutdown that seems to be happen if I start hosted mode and it can't connect to the server: http://crash-stats.mozilla.com/report/index/bp-e1440d75-31d8-4eac-b455-a6d6f2091119 I'm running the OOPHM plugin v 0.9.6820.20091110174102, installed from the missing-plugin appspot page. I'll try building from source and see if I can turn on some additional debugging for this. Not really sure what's causing it. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] TypeOracle allTypes including types not in a source path
Hey all, Sorry to keep spamming GWT 2.0 issues. I've run into a difference in how TypeOracle works that seems to have changed in GWT 2.0. In previous versions, calling context.getTypeOracle().getTypes() from a generator would limit itself to types available on the source paths. I have some code that took advantage of that to build a quick-and-dirty annotation-based dependency-injection framework. It generates a single factory class which contains methods to initialize all of the injectable classes (and injectee) classes available on the source path. It seems that getTypeOracle().getTypes() is now returning all classes available on the classpath, rather than limiting itself to source- specified classes. These classes are picked up by the factory and generated into the new class, which then ends up causing a java.lang.NoClassDefFoundError when this class is instantiated: Caused by: java.lang.NoClassDefFoundError: XXX at java.lang.Class.getDeclaredConstructors0(Native Method) at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357) at java.lang.Class.getDeclaredConstructors(Class.java:1808) at com .google .gwt .dev .shell .DispatchClassInfo .lazyInitTargetMembersUsingReflectionHelper(DispatchClassInfo.java:163) at com .google .gwt .dev .shell.DispatchClassInfo.lazyInitTargetMembers(DispatchClassInfo.java: 146) at com .google .gwt.dev.shell.DispatchClassInfo.getMemberId(DispatchClassInfo.java:55) at com.google.gwt.dev.shell.CompilingClassLoader $DispatchClassInfoOracle.getDispId(CompilingClassLoader.java:166) at com .google .gwt .dev.shell.CompilingClassLoader.getDispId(CompilingClassLoader.java:930) at com.google.gwt.dev.shell.Jsni $JsSourceGenWithJsniIdentFixup.visit(Jsni.java:105) The exception itself is probably a bug (not sure why it didn't trigger a compiler error), but I'm not sure if TypeOracle.getTypes() returning all types is by design. I've been looking for an excuse to ditch the custom IoC code for Guice- GWT, however. Matt. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Development mode in Chrome content scripts (and other strange places)
Hey all, We're using GWT in a lot of places that aren't traditional webpages (currently a Firefox extension and a Chrome plugin). We've rolled our support for OOPHM in Firefox chrome code, but Chrome content scripts are going to be a different story. For now, our code is simple enough that we can test it as part of the content code itself, but we have to mock out any code that uses a Port to talk with the background page. Any ideas on how we might introduce development mode into this environment? Since the content script code has a scripting context separate from the content itself, booting up the GWT component in the page isn't really an option. The NPAPI plugin would end up communicating with the page itself rather than the content script we are attempting to start. It might be possible to start up the development mode plugin in another window and use postMessage calls to proxy the hosted mode events across. To support our headless Firefox component, we're popping up a XUL window to host the plugin for the lifetime of the browser. This approach might work here for content scripts, but it might require some decoupling of the hosted mode plugin from its immediate scripting environment. Thoughts? Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Compiler Optimization Thought: Class merging
I think the impact of anonymous classes will be significantly less once union types are implemented. As it stands right now, every anonymous class gets typeinfo and getClass because some code elsewhere is calling it on an variable that can't be tightened more than Object. On 2009-11-03, at 10:23 AM, Scott Blum sco...@google.com wrote: Hi Nathan, We've talked about doing something like this, under various names, including inner class elision. It seems worthwhile in the abstract, to reduce client-side object counts. What I'm not sure of is how hard it really would be to get right. In the past we've had discussions about the attributes of the classes to be merged. They'd need to be singletons within their containing class, final, initialized up front.. and references wouldn't be allowed to escape into the wild. And that last one is the real sticking point for what you want... allowing references to escape gets very problematic, but not allowing them to escape makes it very hard to actually get it to kick in for the exact case you're trying to solve. Scott On Tue, Nov 3, 2009 at 11:43 AM, Nathan Wells nwwe...@gmail.com wrote: As I was developing this morning, I came across a trade-off that I wasn't happy with. Namely, as I create handlers and other interface implementations in a given class, the implementations create new classes, which adds additional, unnecessary code into the compiled output. One way around this is to sacrifice my code readability and simply have the containing class implement those interfaces. For example, class Foo { static class BarHandler implements ClickHandler, KeyDownHandler { ... } static class FooCommand implements Command { ... } ... class body that doesn't implement and onClick, onKeyDown or execute method... } could compile to something like class Foo implements ClickHandler, KeyDownHandler, Command { ... merged implementations ... } Of course, I'm operating under a few assumptions (based on my watching this group and the developer group, and my lack of knowledge about how the compiler actually works ;) 1. This isn't already done, 2. Adding more classes actually significantly increases the bulk of compiled output. 3. The amount of time to add this optimization would be less than the pain of the trade-off I'm dealing with. Let me know what you think, Nathan --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Random Thought: Compiler transformation Sync - Async
The API is just a skeleton to experiment with all the strong-typing that would go along with porting Oni to Java, so there's not much there. It helped prove that the concept was sound if I had a chance to take a go at it and gave me some code to look at while planning it out. There's still a some porting work to take the Oni code and Java- fy it. I think this is the right first step - once you have a solid async library like this, there are some interesting things you can build on it (as Stratified JavaScript builds on Oni: http://www.croczilla.com/blog/17) . On 2-Nov-09, at 6:17 AM, Bart Guijt wrote: Just checked out Oni - interseting indeed, could have used something like that in several recent GWT projects I did. You mentioned you roughed out an equivalent GWT API - is it publicly accessible? --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Random Thought: Compiler transformation Sync - Async
Exactly - a lot of our code is basically something like mark UI as busy, fetch A and B, then mark UI as ready or mark UI as busy, fetch A, then fetch B from results of A, then mark UI as ready. In other places, we'll start a set of asynchronous operations, then have to cancel them (if a widget is unloaded, for example). There's no dire need for continuations, but there's definitely a structured set of operations that repeats itself and could be turned into a useful library of async primitives. Matt. On 2-Nov-09, at 2:35 PM, Bruce Johnson wrote: At a quick glance, something like this seems way better than a wholesale sync-async rewriter. It's actually important not to hide genuine asyncrony from the developer, because it represents an actual app state the developer should account for (e.g. what UI should be disabled while an async operation is pending? do you show a please wait or not?). What we'd want is a framework that makes it easier to produce and reason about necessarily async patterns. On Mon, Nov 2, 2009 at 12:42 PM, Matt Mastracci matt...@mastracci.com wrote: The API is just a skeleton to experiment with all the strong-typing that would go along with porting Oni to Java, so there's not much there. It helped prove that the concept was sound if I had a chance to take a go at it and gave me some code to look at while planning it out. There's still a some porting work to take the Oni code and Java- fy it. I think this is the right first step - once you have a solid async library like this, there are some interesting things you can build on it (as Stratified JavaScript builds on Oni: http://www.croczilla.com/blog/17) . On 2-Nov-09, at 6:17 AM, Bart Guijt wrote: Just checked out Oni - interseting indeed, could have used something like that in several recent GWT projects I did. You mentioned you roughed out an equivalent GWT API - is it publicly accessible? --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Random Thought: Compiler transformation Sync - Async
I find that there are two sources of a lot of boilerplate code for the async stuff I work on: 1. State machines 2. Coordinating multiple asynchronous events (ie: timers, multiple inflight requests and user events) For #1, the code usually ends up as a set of enums for simple states or a set of polymorphic classes for more complicated cases. For #2, we've got some simple classes that allow you to run actions based on certain trigger conditions. Both of these patterns show up a lot in our code and while we've done a bit to try and reduce the impact of these cases, we're still paying a lot of boilerplate lines of async tax per screen. There might be a way to approach this like Oni does (http://www.croczilla.com/oni ): provide a set of asynchronous building blocks that you can use to coordinate asynchronous events. You end up building an asynchronous lambda function that can be applied as needed. No compiler magic needed: the async callbacks throughout the API provide the equivalent of continuations. I roughed out a GWT API for this some time ago and it seemed like it would be reasonably easy to do as a third-party library. Matt. On 1-Nov-09, at 9:31 AM, Bart Guijt wrote: On 1 nov 2009, at 1 nov, 17:24, John Tamplin wrote: On Sun, Nov 1, 2009 at 10:38 AM, Bart Guijt bgu...@gmail.com wrote: Although I concur with Bob Vawter's comment, I still think there's a place for a compiler transformation like this. The proposal is not to meet incompetence levels of Java programmers, it is to enable existing Java libraries in GWT client code (AFAIC). I think that is precisely the reason you don't want to allow it -- existing libraries are written with the implicit assumption that such calls are synchronous. The whole idea behind runAsync is that by explicitly specifying where the split point happens, the programmer can structure the code better to handle the load there, the associated delay, and possible failures. You can see the problems MS has had trying to transparently turn synchronous calls into asynchronous ones first with Volta and then another attempt I can't find the name of quickly. Also, it isn't just this method that would have to be written to pass a continuation but everything on the callstack, and if just one such method were possibly called basically the entire program would have to get transformed. Well, you got a point :-) Didn't know Microsoft attempted the same thing. Thanks for your reply! Bart Guijt --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Adding a DOM com.google.gwt.dom.client.Window class?
Joel, This is definitely a can of worms! I spent some time thinking through the some of these points. Some additional comments inline... On 17-Aug-09, at 10:02 AM, Joel Webber wrote: At any rate, we *do* need something like this, and now seems as good a time as any to bring it up. In fact, there are several such classes that need to be moved out of gwt.user.client into a more sensible place (and others that still need to be written). What they have in common is that they have nothing to do with widgets, but are not core because they assume the existence of a real web browser (as opposed to other potential Javascript targets such as Flash). The ones that come to mind are: Existing: - Window - Location - Cookies (though maybe Document just needs its cookie property implemented) - Timer (this is implemented on top of Window.set[Interval Timeout]()) - History (there are both the native history object, and the GWT history implementation to consider) - [Incremental Deferred]Command (Smells like core, but requires Timer to work) One consideration this raises is that some have internal state associated with them. For instance, both the Cookies class and Location classes have precomputed maps of data. How can you ensure that a service is a singleton for a given native object (or is it best to provide this for the default window and document only)? There's also the issue with cleaning up objects when documents/windows are unloaded, since the lifetime of the GWT module may be significantly longer than the windows it references. I suppose the cleanup could be handled via some global per-window unload cleanup queue attached to a specific window's unload handler. Additionally, how can you handle multiple GWT modules that may reference the same native window or document? History and location may be useful to expose as simple JSO wrappers over the native browser's objects. The full GWT history implementation would probably be less useful on a window that didn't contain a GWT module (esp. considering that newItem() is so different on every browser). For Timer and IncrementalCommand, I suspect there wouldn't be much lost if they were left as global services. The only advantage to having per-window timers that I can think of right now would be scoping the lifetime of the timer to the window itself (is this even consistent across browsers?). I think it might be sufficient to create a rebind point for creating timers for different environments. FWIW, this is the code we use to simulate Timer when running as a Firefox extension. It would be a lot cleaner as a timer rebind and I imagine that AIR and other JS-but-not-HTML environments would be very similar: window.setTimeout = function(callback, timeout) { var timer = Components.classes[@mozilla.org/timer; 1].createInstance(Components.interfaces.nsITimer); var handle = {timer: timer, active: 1, callback: callback}; var doNotify = function() { manag...@com.dotspots.mozilla.extensionmanager::activeOneShotTimers--; delete handle.active; delete handle.callback; delete handle.timer; manag...@com.dotspots.mozilla.extensionmanager::safeCallback(Lcom/ google/gwt/core/client/JavaScriptObject;)(callback); } timer.initWithCallback({notify: doNotify}, timeout, Components.interfaces.nsITimer.TYPE_ONE_SHOT); manag...@com.dotspots.mozilla.extensionmanager::activeOneShotTimers++; timers.push(handle); return timers.length - 1; } New: - Selection (this is pretty tricky, because selection on IE is so amazingly weird) - Others? Selection would be very useful, even if it was limited to some simple operations at first (exists, get text, delete, replace). The W3C selection API is very useful, but I'm not sure if there's a compelling use case outside of Google Wave to merit the effort required (I had experimented with this a while back, but it's difficult to get consistent results between webkit/gecko, let alone with IE in the picture :)!). There's a few miscellaneous DOM services that would be useful, such as the DOM tree walking service and xpath functions. Neither of those is complex enough to be consequential, so they probably wouldn't factor into any design. The main hold up for me has been figuring out how to move the existing classes to a more sensible module, and precisely what that module is. Selection and Window could arguably be considered par of DOM (WebKit has a DOMWindow class, even though the W3C doesn't consider it part of the DOM per se). It is not immediately obvious to me where the others should live, though -- should we have a Browser module, for example? I
[gwt-contrib] Adding a DOM com.google.gwt.dom.client.Window class?
Hi all, I've been hacking around the lack of a true JavaScriptObject window in GWT for a while and I was wondering if there was any interest in me providing a patch for it. While the current com.google.gwt.user.client.Window works for most cases, you aren't able to interact with other windows in the system without resorting to hand-rolled JSNI. For example, calling com.google.gwt.user.client.Window::open() doesn't provide you a way to close the window that was just opened. I propose adding a JSO subclass to the com.google.gwt.dom.client package. For the first patch there would be a handful of uncontroversial methods on it (further patches could provide the remainder of the functionality that exists in the com.google.gwt.user.client.Window): Document getDocument(); void alert(String); String prompt(String); void close(); I would also propose adding the following method to Document to get its associated window. On standards-compliant browsers, this would map to defaultView. On IE, this would map to parentWindow: Window getParentWindow() Thoughts? Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: [google-web-toolkit] r5959 committed - Function Clustering, improves gzip compression by significant margin. ...
Ray, This is really cool! On 13-Aug-09, at 1:22 PM, codesite-nore...@google.com wrote: Revision: 5959 Author: cromwellian Date: Thu Aug 13 12:21:36 2009 Log: Function Clustering, improves gzip compression by significant margin. Top-level block restructuring for IE7 is now done purely via a text-transformation, while in-method block restructuring is done via the AST. Block restructuring is only performed for IE permutations (or permutations with no user.agent specified). http://code.google.com/p/google-web-toolkit/source/detail?r=5959 Added: /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ JsAbstractTextTransformer.java /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ JsFunctionClusterer.java /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ JsIEBlockTextTransformer.java Modified: /trunk/dev/core/src/com/google/gwt/dev/jjs/ JavaToJavaScriptCompiler.java === --- /dev/null +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ JsAbstractTextTransformer.java Thu Aug 13 12:21:36 2009 @@ -0,0 +1,117 @@ +/* + * Copyright 2009 Google Inc. + * + * 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. + */ +package com.google.gwt.dev.jjs.impl; + +import com.google.gwt.core.ext.linker.StatementRanges; +import com.google.gwt.core.ext.linker.impl.StandardStatementRanges; + +import java.util.ArrayList; + +/** + * Base class for transforming program text. + */ +public abstract class JsAbstractTextTransformer { + + protected String js; + + protected StatementRanges statementRanges; + + public JsAbstractTextTransformer(String js, StatementRanges statementRanges) { +this.js = js; +this.statementRanges = statementRanges; + } + + public JsAbstractTextTransformer(JsAbstractTextTransformer xformer) { +this.js = xformer.getJs(); +this.statementRanges = xformer.getStatementRanges(); + } + + public abstract void exec(); + + protected void addStatement(String code, StringBuilder newJs, + ArrayListInteger starts, ArrayListInteger ends) { +beginStatement(newJs, starts); +newJs.append(code); +endStatement(newJs, ends); + } + + protected void endStatement(StringBuilder newJs, ArrayListInteger ends) { +ends.add(newJs.length()); + } + + protected void beginStatement(StringBuilder newJs, + ArrayListInteger starts) { +starts.add(newJs.length()); + } + + public String getJs() { +return js; + } + + public StatementRanges getStatementRanges() { +return statementRanges; + } + + protected String getJsForRange(int stmtIndex) { +return js.substring(statementRanges.start(stmtIndex), +statementRanges.end(stmtIndex)); + } + + /** + * Dump functions and fragments back into a new JS string, and calculate a new + * StatementRanges object. + */ + protected void recomputeJsAndStatementRanges(int[] stmtIndices) { + +StringBuilder newJs = new StringBuilder(); +ArrayListInteger starts = new ArrayListInteger(); +ArrayListInteger ends = new ArrayListInteger(); + +beginStatements(newJs, starts, ends); +for (int i = 0; i stmtIndices.length; i++) { + String code = getJsForRange(stmtIndices[i]); + addStatement(code, newJs, starts, ends); +} +endStatements(newJs, starts, ends); + +assert +starts.size() == ends.size() : +Size mismatch between start and + end statement ranges.; +assert starts.get(0) == 0 ends.get(ends.size() - 1) == newJs +.length() : statement ranges don't cover entire JS output string.; + +StandardStatementRanges newRanges = new StandardStatementRanges(starts, +ends); +js = newJs.toString(); +statementRanges = newRanges; + } + + /** + * Called if any operations need to be performed before all statements have + * been processed. + */ + protected void beginStatements(StringBuilder newJs, ArrayListInteger starts, + ArrayListInteger ends) { + } + + /** + * Called if any operations need to be performed after all statements have + * been processed. + */ + protected void endStatements(StringBuilder newJs, ArrayListInteger starts, + ArrayListInteger ends) { + } +} === --- /dev/null +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ JsFunctionClusterer.java
[gwt-contrib] Re: New GWT RPC project: gwt-rpc-plus
Alex, We're using this to generate the classes we'll be using for our own RPC going forward. It won't help you serialize existing DTOs, but it will offer a shortcut if you want to create a parallel tree of objects for RPC. It sounds like the only part that might be relevant to your needs is the Thrift support, but you'll need to do the grunt work of writing IDL for the existing classes (or writing your own code generator to do the same). Let me know if it turns out to be useful for you, or if there's something we can add to the library to enable an alternate solution. Matt. On 12-Aug-09, at 3:17 AM, Alex Bertram wrote: Hi Matt, I'm just checking out of svn gwt-rpc-plus now. I'm hoping I can use it to wire up a solution to what seems like a simple problem: I want GWT to serialize my DTO object and post it to a servlet that will generate a pdf/excel file/etc for download. The DTOs are numerous / complex enough that writing some kind parallel serializer is prohibitive. Have you come across this use case before ? Thanks, Alex On Aug 8, 8:53 pm, Matt Mastracci matt...@mastracci.com wrote: Bart, One principle of design for the alternate RPC framework in this library was reducing the number of non-JSO classes generated in the final output, at the expense of developer convenience and flexibility. At one point, RPC classes and serializers were nearing 20% of our compiled output. By reducing some of the flexibility of RPC (ie, with machine built overlay types and collections that implement just enough to get by), we can effectively reduce the RPC footprint in terms of wire size, code size and serialization/deserialization time. Note that bobv's direct-eval RPC branch should come with its own significant performance gains and code/wire size reductions. It may be worth investigating the performance of trunk for your specific case as well. Of course, if GWT RPC is sufficient for your use, you can always use this library to add cross-domain transport of RPC payloads or add out-of-band context to the request/response data. I'd be interested in hearing any thoughts or suggestions you might have. Thanks, Matt. On 2009-08-08, at 10:16 AM, Bart Guijt bgu...@gmail.com wrote: To me this sounds *very* interesting. Makes me want to find out all the details why GWT-RPC is as it is, if the simpler JS collections improve upon performance, memory footprint and (permutation) code size etc. Efforts like this might have a big impact on mobile GWT applications, which are my primary interest. Checking the sources out right now :-) Bart Guijt E: bgu...@gmail.com T: +31 6 30408987 Check out my blog:http://bart.guijt.me/blog/ A pizza with the radius 'z' and thickness 'a' has the volume pi*z*z*a On 8 aug 2009, at 8 aug, 04:58, Matt Mastracci wrote: Hey all, We've been working on a number of RPC enhancements locally and thought that it might be helpful to open-source some of them (prompted by a recent suggestion from Ray Cromwell). I've created a new Google Code project that encapsulates them here: http://code.google.com/p/gwt-rpc-plus/ It's an umbrella project for a number of RPC enhancements that we're using. It includes a set of building blocks and some higher-level code that builds on them to enhance the current GWT RPC functionality: 1. A set of 'bare-metal', strongly-typed JS collections optimized for both RPC and client-side use. These collections are designed to mimic (but not fully support) the interfaces of the standard Java List, Map and Set. They are code-generated and based on JavaScriptObject (see here:http://code.google.com/p/gwt-rpc-plus/source/browse/#svn/ trunk/ gwt-rpc-plus/gwt/com/dotspots/rpcplus/client/jscollections). They are essential to the Thrift RPC system (mentioned below), but are useful as their own standalone collections. 2. Alternative JSON and text transports, including a cross-domain transport using window.name and standard XMLHttpRequest communication. 3. A set of fast utility classes to parse and emit JSON using browser- native code where possible (ie: JSON.parse/stringify, eval/uneval). 4. A way to plug alternative transports into GWT RPC (based on a technique similar to this:http://timepedia.blogspot.com/2009/04/gwt-rpc-over-arbitrary-transpor ... ) . It currently includes a way to easily replace the RPC transport with any text transport (including the window.name transport mentioned above). 5. A Thrift-based, versioned RPC framework that can replace GWT RPC entirely (built on top of the above-mentioned pieces). The code in the library was extracted from a bunch of code scattered throughout our project. I'm still working on refactoring and cleaning up parts of it, so it's likely to change over the next few weeks. None of the architecture is set in stone, so anyone interested in helping contribute/architect is welcome
[gwt-contrib] Re: New GWT RPC project: gwt-rpc-plus
David, The new RPC framework in the library currently suffers from the reference limits of Thrift itself, which are 'no self or forward references'. This effectively limits the object nesting depth. Additionally, all the de/serialization is done via native primitives which seem to handle larger structures well. You don't necessarily have to use Thrift here. I do have some old code (which hasn't been imported here yet unfortunately) that generate client side API stubs that can receive standard API calls made by other client code. I'll dig it up and unrot it. I had completely forgotten about that code until now. By pairing the code with a cross module transport (function call, postMessage or location hash), you'll be able to communicate between two modules using code that looks identical to standard RPC. On 2009-08-09, at 11:56 PM, David david.no...@gmail.com wrote: Matthew, Now you got me interested! I currently have some JSNI code to communicate between different modules, I would love to take this out and replace it with something RPC style. Can your RPC library handle complex structures (where the current 1.x GWT RPC layers gives stackoverflow or out of memory) ? David Note that we'll be doing some cool stuff with our library in the future that we can't easily do with GWT RPC, like generating raw Javascript bindings for third-party developers to interface with our API and using it for module-to-module cross-domain communication. On Aug 9, 1:00 am, Miroslav Pokorny miroslav.poko...@gmail.com wrote: @Matt I was just wondering if it were possible to specify a concrete substitute for an interface type - this would this help solve the too many serializer problem. By too many Serializers i mean of course the need for the generator to create Serializers for all concrete types implementing List etc. Service { @Annotation(java.util.ArrayList.class); ListType method( int parameter ); } In the above case no matter what type of List the server sent, the client would always get an ArrayList. Naturally the same annotation would appear on value types with List properties. Perhaps something similar could be used to whitelist sub class serializer generation. Comments ? On Sun, Aug 9, 2009 at 4:53 AM, Matt Mastracci matt...@mastracci.comwrote: Bart, One principle of design for the alternate RPC framework in this library was reducing the number of non-JSO classes generated in the final output, at the expense of developer convenience and flexibility. At one point, RPC classes and serializers were nearing 20% of our compiled output. By reducing some of the flexibility of RPC (ie, with machine built overlay types and collections that implement just enough to get by), we can effectively reduce the RPC footprint in terms of wire size, code size and serialization/deserialization time. Note that bobv's direct-eval RPC branch should come with its own significant performance gains and code/wire size reductions. It may be worth investigating the performance of trunk for your specific case as well. Of course, if GWT RPC is sufficient for your use, you can always use this library to add cross-domain transport of RPC payloads or add out-of-band context to the request/response data. I'd be interested in hearing any thoughts or suggestions you might have. Thanks, Matt. On 2009-08-08, at 10:16 AM, Bart Guijt bgu...@gmail.com wrote: To me this sounds *very* interesting. Makes me want to find out all the details why GWT-RPC is as it is, if the simpler JS collections improve upon performance, memory footprint and (permutation) code size etc. Efforts like this might have a big impact on mobile GWT applications, which are my primary interest. Checking the sources out right now :-) Bart Guijt E: bgu...@gmail.com T: +31 6 30408987 Check out my blog:http://bart.guijt.me/blog/ A pizza with the radius 'z' and thickness 'a' has the volume pi*z*z*a On 8 aug 2009, at 8 aug, 04:58, Matt Mastracci wrote: Hey all, We've been working on a number of RPC enhancements locally and thought that it might be helpful to open-source some of them (prompted by a recent suggestion from Ray Cromwell). I've created a new Google Code project that encapsulates them here: http://code.google.com/p/gwt-rpc-plus/ It's an umbrella project for a number of RPC enhancements that we're using. It includes a set of building blocks and some higher- level code that builds on them to enhance the current GWT RPC functionality: 1. A set of 'bare-metal', strongly-typed JS collections optimized for both RPC and client-side use. These collections are designed to mimic (but not fully support) the interfaces of the standard Java List, Map and Set. They are code-generated and based on JavaScriptObject (see here:http://code.google.com/p/gwt-rpc-plus/source/browse/#svn
[gwt-contrib] Re: New GWT RPC project: gwt-rpc-plus
Bart, One principle of design for the alternate RPC framework in this library was reducing the number of non-JSO classes generated in the final output, at the expense of developer convenience and flexibility. At one point, RPC classes and serializers were nearing 20% of our compiled output. By reducing some of the flexibility of RPC (ie, with machine built overlay types and collections that implement just enough to get by), we can effectively reduce the RPC footprint in terms of wire size, code size and serialization/deserialization time. Note that bobv's direct-eval RPC branch should come with its own significant performance gains and code/wire size reductions. It may be worth investigating the performance of trunk for your specific case as well. Of course, if GWT RPC is sufficient for your use, you can always use this library to add cross-domain transport of RPC payloads or add out-of-band context to the request/response data. I'd be interested in hearing any thoughts or suggestions you might have. Thanks, Matt. On 2009-08-08, at 10:16 AM, Bart Guijt bgu...@gmail.com wrote: To me this sounds *very* interesting. Makes me want to find out all the details why GWT-RPC is as it is, if the simpler JS collections improve upon performance, memory footprint and (permutation) code size etc. Efforts like this might have a big impact on mobile GWT applications, which are my primary interest. Checking the sources out right now :-) Bart Guijt E: bgu...@gmail.com T: +31 6 30408987 Check out my blog: http://bart.guijt.me/blog/ A pizza with the radius 'z' and thickness 'a' has the volume pi*z*z*a On 8 aug 2009, at 8 aug, 04:58, Matt Mastracci wrote: Hey all, We've been working on a number of RPC enhancements locally and thought that it might be helpful to open-source some of them (prompted by a recent suggestion from Ray Cromwell). I've created a new Google Code project that encapsulates them here: http://code.google.com/p/gwt-rpc-plus/ It's an umbrella project for a number of RPC enhancements that we're using. It includes a set of building blocks and some higher-level code that builds on them to enhance the current GWT RPC functionality: 1. A set of 'bare-metal', strongly-typed JS collections optimized for both RPC and client-side use. These collections are designed to mimic (but not fully support) the interfaces of the standard Java List, Map and Set. They are code-generated and based on JavaScriptObject (see here: http://code.google.com/p/gwt-rpc-plus/source/browse/#svn/trunk/ gwt-rpc-plus/gwt/com/dotspots/rpcplus/client/jscollections). They are essential to the Thrift RPC system (mentioned below), but are useful as their own standalone collections. 2. Alternative JSON and text transports, including a cross-domain transport using window.name and standard XMLHttpRequest communication. 3. A set of fast utility classes to parse and emit JSON using browser- native code where possible (ie: JSON.parse/stringify, eval/uneval). 4. A way to plug alternative transports into GWT RPC (based on a technique similar to this: http://timepedia.blogspot.com/2009/04/gwt-rpc-over-arbitrary-transports-uber.html ) . It currently includes a way to easily replace the RPC transport with any text transport (including the window.name transport mentioned above). 5. A Thrift-based, versioned RPC framework that can replace GWT RPC entirely (built on top of the above-mentioned pieces). The code in the library was extracted from a bunch of code scattered throughout our project. I'm still working on refactoring and cleaning up parts of it, so it's likely to change over the next few weeks. None of the architecture is set in stone, so anyone interested in helping contribute/architect is welcome to join in. Thanks! Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Any hints on why GWT's JUnit tests would be consistently timing out for me?
Issac, Are you running under Linux? If so, your embedded Mozilla browser may be showing a prompt, but its window is hidden. Try running with - notHeadless. On 2009-08-08, at 11:55 AM, Isaac Truett itru...@gmail.com wrote: I'm trying to run the unit tests in GWT trunk. I've tried with Ant and with the JUnit UI in Eclipse, but I'm seeing many of the suites exceed the 60 second timeout: [junit] - 1 client(s) haven't responded back to JUnitShell since the start of the test. I'm at a loss to figure out what it's waiting on. I've sat and watched my CPU usage and it isn't anywhere near topping out for the minute it takes the test to time out. I've tried running just a single test class or a single method using the Eclipse UI and even a do-nothing test times out. I'm assuming it's something wonky on my end. Anyone have any suggestions? Thanks, Isaac --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] New GWT RPC project: gwt-rpc-plus
Hey all, We've been working on a number of RPC enhancements locally and thought that it might be helpful to open-source some of them (prompted by a recent suggestion from Ray Cromwell). I've created a new Google Code project that encapsulates them here: http://code.google.com/p/gwt-rpc-plus/ It's an umbrella project for a number of RPC enhancements that we're using. It includes a set of building blocks and some higher-level code that builds on them to enhance the current GWT RPC functionality: 1. A set of 'bare-metal', strongly-typed JS collections optimized for both RPC and client-side use. These collections are designed to mimic (but not fully support) the interfaces of the standard Java List, Map and Set. They are code-generated and based on JavaScriptObject (see here: http://code.google.com/p/gwt-rpc-plus/source/browse/#svn/trunk/ gwt-rpc-plus/gwt/com/dotspots/rpcplus/client/jscollections). They are essential to the Thrift RPC system (mentioned below), but are useful as their own standalone collections. 2. Alternative JSON and text transports, including a cross-domain transport using window.name and standard XMLHttpRequest communication. 3. A set of fast utility classes to parse and emit JSON using browser- native code where possible (ie: JSON.parse/stringify, eval/uneval). 4. A way to plug alternative transports into GWT RPC (based on a technique similar to this: http://timepedia.blogspot.com/2009/04/gwt-rpc-over-arbitrary-transports-uber.html) . It currently includes a way to easily replace the RPC transport with any text transport (including the window.name transport mentioned above). 5. A Thrift-based, versioned RPC framework that can replace GWT RPC entirely (built on top of the above-mentioned pieces). The code in the library was extracted from a bunch of code scattered throughout our project. I'm still working on refactoring and cleaning up parts of it, so it's likely to change over the next few weeks. None of the architecture is set in stone, so anyone interested in helping contribute/architect is welcome to join in. Thanks! Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Better support of IE6 for ImageResourceGenerator
On 6-Aug-09, at 9:57 AM, John Tamplin wrote: If the transparency is just binary, then IE6 already supports PNG transparency, right? Aside from the hassle of detecting if a one- bit alpha channel will do, I think the J2D libraries we currently use won't generate one-bit alpha channels (I could be remembering incorrectly however), so we would have to find something else. John, That's correct: IE6 supports PNG with 1-bit alpha transparency. More specifically, IE6 supports PNG files with a palette and a 100% transparent color at index 0. Java doesn't generate PNG files with this property. We have a specific build step in our environment that post-processes all the PNG files to force this. Conditional comments serve IE6 the same CSS file, but from a subdirectory that contains the IE6-processed images instead. We end up with a lot of dithering on some of our output images, but it still works on IE6. Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] RPC forward/backward compat
Hey all, We've been struggling with the issue of RPC forward/backward incompatibility for a little while and I thought I'd bring it to the list for discussion. As some of you know, one of our use-cases for GWT is embedding the compiled JS in a Firefox extension. Unfortunately, the lifetime of the code in the extension cannot be easily tied to the lifetime of the code on the server. The consequence of this is that when our server- side code is updated, the client-side code starts throwing IncompatibleRemoteService exceptions until the user updates. We also see this issue briefly during our website code updates - our load- balanced servers are incrementally updated with background code which means that for a brief period, some active users get RPC exceptions. There's a number of ways we can work around it for the extension (forcing the user to update is the easiest), but this is somewhat inconvenient for our users. The ideal solution would be offering a forward/backward compatible RPC protocol that would allow some flexibility in versioning between client and server. I'd like to be able to push out a server that is backward-compatible aware and have it able to serve downlevel requests for some period of time. For our website, the period of time would be a few minutes while all the backends update and the static code is pushed out. For our extension, this period could be on the order of days or even a week. One of the skunkworks projects I've been working for a while is a GWT port of Thrift (a versioned protocol similar to Protobuf), basically a direct eval RPC library that would let us use the versioned protocol to replace our RPC code. One of the big downsides is that we'd lose a lot of the niceties of GWT RPC, mostly smart objects and polymorphism. It's getting close to completion, but it's been a while since I've last had a chance to work on it and the new deRPC branch has shown up. Is the concept of versioning something that belongs in the core GWT RPC code, or is this something better suited for an external library? Thanks, Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: RPC forward/backward compat
On 24-Jul-09, at 6:39 PM, BobV wrote: I have a design wave going on about how to add this to the new RPC implementation. Here's a cruddy copy-and-paste of the current state of the document. Bob, this is awesome! Is the plan to land this as part of deRPC, or is this a future feature that will land beyond deRPC? Also, will this be supported on methods themselves? For instance, can I mark a new method parameter as @Optional so that older clients don't need to provide it? Conversely, could we remove a parameter from a method and still support clients sending data with the old signature? One more question... Is it possible to incorporate the idea of numbered fields into this design? This would make it much easier to interop with Thrift (and possibly protobuf), both of which use numeric keys for versioning. We'd probably write some code to output GWTRPC- compatible Thrift objects from our IDL, which means that we'd have numeric keys already set up and we wouldn't have to worry about versioning issues when renaming fields. Thanks, Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: RPC forward/backward compat
On 24-Jul-09, at 9:11 PM, BobV wrote: Also, will this be supported on methods themselves? For instance, can I mark a new method parameter as @Optional so that older clients don't need to provide it? Conversely, could we remove a parameter from a method and still support clients sending data with the old signature? I could go either way on that. My thinking here was to just use the existing Java method override semantics. As long as the servlet has a method that will accept the parameters actually sent by the client, the request would proceed. The older methods wouldn't need to be in the RPC interfaces themselves, just (deprecated) methods on the servlet. From a dev perspective, it might be easiest if we could make methods optional directly on the method. It more closely matches our current modus operandi w.r.t. thrift - the new parameters are added directly to the method, while the old ones are simply removed. Regardless of the method compatibility story, it would be very helpful to have an RPC validation utility: given this set of client RPC manifests, can we successfully parse the requests? One more question... Is it possible to incorporate the idea of numbered fields into this design? This would make it much easier to interop with Thrift (and possibly protobuf), both of which use numeric keys for versioning. We'd probably write some code to output GWTRPC- compatible Thrift objects from our IDL, which means that we'd have numeric keys already set up and we wouldn't have to worry about versioning issues when renaming fields. I'm not really sure why you'd want to do this. The numbering / tags in protocol buffers are more of an implementation detail to minimize the number of bytes in the payload and to provide a meaningful way to support the use of the protocol message across different languages. If you have a concrete use case, please give me an example. Good point- I'm not sure I can really offer a good example that would justify this effort. The only reason I can see to do it would be to prevent field renames from breaking serialization compatibility (something we take for granted today). That can be mitigated through developer education and as it stands, there's nothing in this model that would prevent us from generating GWT-compatible stubs from our thrift IDL. Thanks for answering my questions, Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Optimizing away the builder pattern
I've been pondering an SSA structure for the compiler that would make some of this stuff a lot easier to deal with. Instead of keeping the AST for the Java and JS trees around, we'd put everything into a unified data flow graph in memory (with appropriate side-effect barriers), optimize the graph, then reconstitute Java and JS code as appropriate. It's a huge undertaking, but there's some bonus end-results (some of these fall out of the process of converting between AST and SSA forms: - Many optimizations would now apply to both Java and JS code - Cross-language Java-JS inlining and static evaluation would be easier - Easier inlining/common subexpression elimination - More opportunities for static evaluation - Incremental type tightening - the compiler could make more methods static by knowing more about types/nullness deep within the data flows: if (x instanceof Blah) { ((Blah)x).foo(); } By traversing the data flow graph, the compiler would be able to see that the JS object was effectively equivalent to the associative array literal { 'a': 1, 'b': 2 } before it was even accessed by other code. In cases where the developer is building other complex datastructures, the compiler could potentially replace those with fully baked equivalents as needed. Matt. On 16-Jun-09, at 9:59 AM, Ray Cromwell wrote: Even before the inliner gets it, a JSO chained expression like a().b().c() is going to look like c(b(a())) so the inliner can only inline the first call. Automatically introducing temporaries would seem a lot harder. You'd have to teach the compiler that 'this' is effectively final, and therefore any method returning this, effectively always returns the same value, regardless of side effects. Then, you'd have to introduce the idea that the compiler can introduce temporaries (speculatively), and later use common subexpression elimination to detect multiple identical ones and hoist them out. e.g. c(b(a())) becomes var t1, t2, t3; t1 = c(t2 = b(t3 = a())) then, recognizing the that t1=t2=t3=builder=a() with copy propagation t1 = builder a(t1) b(t1) c(t1) and now they can be inlined. This just seems hard to me, since introducing temporaries is speculative and you'd have introduce another pass to remove them in the cases where they provided no benefit. However, this could end up leading to infinite loops if you're not careful. -Ray On Mon, Jun 15, 2009 at 6:11 PM, Brian Stolerbsto...@google.com wrote: Hi gwtc, I was playing with using super-source to emulate some existing code that uses a builder pattern and make it efficient in GWT as a JavaScriptObject. I was hoping that the I could make the Builder just compile away, but that doesn't seem to be happening. I started debugging in JsInliner but started to get a bit lost. This is using svn r5557 on trunk FYI (very recent). What I am seeing is that if you use a chaining call pattern, the inliner doesn't realize some of the optimization it can do. Example usage code: void example() { MyData myData = MyData.Builder.create() .setBar(a) .setFoo(b).build(); Window.alert(myData.getBar()); Window.alert(myData.getFoo()); } Output I get (extraneous bits removed, PRETTY mode): function init(){ var myData; myData = $setFoo($setBar(new Object(), 'a'), 'b'); $wnd.alert(myData.bar); $wnd.alert(myData.foo); } function $setBar(this$static, s){ this$static.bar = s; return this$static; } function $setFoo(this$static, s){ this$static.foo = s; return this$static; } However, with this similar code: void example2() { MyData.Builder builder = MyData.Builder.create(); builder.setBar(a); builder.setFoo(b); MyData myData = builder.build(); Window.alert(myData.getBar()); Window.alert(myData.getFoo()); } The code compiles better (no setters): builder = new Object(); builder.bar = 'a'; builder.foo = 'b'; myData = builder; $wnd.alert(myData.bar); $wnd.alert(myData.foo); The biggest issue seemed to be that the inliner didn't introduce a local variable for new Object(), and because of that, it correctly concluded it couldn't keep copying that expression around. (I traced through it having issues due to new having side effects.) Even if I manually create a variable for the Builder at the outset, it still doesn't help. (FYI, I am using new Object() instead of {} to work around http://code.google.com/p/google-web-toolkit/issues/detail?id=3568) I was going to try to dig some more in to the inliner, but any ideas how to improve this? Will a later pass remove useless variable aliasing? (Seems like not from my other example?) If so, I was thinking it might work to have the inliner introduce a local all the time when it is trying to inline a
[gwt-contrib] Re: Changing JsArrayT extends JavaScriptObject to JsArrayT
I do as well - I'm mmastrac. On 15-Jun-09, at 8:02 PM, Ray Cromwell wrote: I do, cromwellian is my id on the sandbox. -Ray On Mon, Jun 15, 2009 at 6:14 PM, Bruce Johnsonbr...@google.com wrote: I'm starting to make a bit o' progress on this. I'll send out a design doc real soon now. BTW, anyone on the Contributors list here have Wave sandbox accounts? Sure would be easier to discuss this in a wave... On Mon, Jun 15, 2009 at 7:54 PM, Stefan Haustein haust...@google.com wrote: Ray, I think we can improve the class over time -- any reasonable starting point (even without iterators or with non-optimal iterators) would help significantly. Stefan On Sat, Jun 13, 2009 at 4:21 AM, Ray Cromwell cromwell...@gmail.com wrote: BTW, the last proposal is very unsafe with some form of escape analysis since it is unsafe to pass references to classes which reference local scope to other scopes. Another possibility is a form of 'destructuring' of Iterator classes by inlining them completely into local scope vs escape analysis and then forgoing separate construction. A simpler way to maintain for-each with JRE collections without creating objects is to change the way that for-each deals with IterableT when T is a List. The compiler could change: for(T x : foo) { ... } where foo is a ListT into for(int i=0; ifoo.size(); ++i) { T x = foo.get(i); } instead of calling foo.iterator() and using Iterator methods. -Ray On Fri, Jun 12, 2009 at 7:31 PM, Ray Cromwellcromwell...@gmail.com wrote: I'm in the process of some final tweaks on GQuery, so I'll look at how much of my private JSArray class I can move over as a patch. One possibility for avoiding Iterator object creation without using flyweights is to introduce a new Iterator type which contains methods which are parameterized by the collection and which use my Extension Method/Category method JSO trick. public class FastIteratorT extends JavaScriptObject { protected FastIterator() {} public S, T extends ListS FastIteratorS make(TS list) { return (FastIteratorS)(GWT.isScript() ? makeWeb() : makeHosted()); } private final native FastIterator makeWeb() /*-{ return 0; }-*/; private final native FastIterator makeHosted() /*-{ return [0]; }-*/; public final int value() { return GWT.isScript() ? valueWeb() : valueHosted(); } public native int valueWeb() /*-{ return this; }-*/; public native int valueHosted() /*-{ return this[0]; }-*/; public native hasNext(ListT list) { return value() list.size(); } public native T next(ListT list) { return list.get(value()++); // unsure if using value() as rvalue will work here } } then you should be able to write code like ListString foo = getList(); FastIteratorString iter = FastIterator.make(foo); while(iter.hasNext(foo)) { String s = iter.next(foo); } Why doesn't this create any additional objects? Because 'iter'/FastIterator is actually a native JS number/scalar type, and what this is really doing is simulating the addition of hasNext()/next() to the number's prototype. We could dispense with the need for an additional parameter if GWT had a magic method for allocating new local variables/symbols in the local scope. Imagine if writing VariableT x = GWT.createVariable(0); was a magic method that just generated a 'var x = 0' declaration, only it promised to always be inlined and do so in the caller's scope. 'Variable' would be a magic class that never creates fields on the actual object themselves and are pruned/removed at runtime. Then you could have FastIterator impersonate a reference to the underlying ListT, and rewrite hasNext()/next() as: VariableInt x = GWT.createVariableInt(0); public boolean hasNext() { return x.get() this.size(); } public T next() { return this.get(x.get()++); // or x.postIncrement() } this would produce code that would create no additional objects as well as maintain Iterator-like interface. -Ray On Thu, Jun 11, 2009 at 7:25 AM, Stefan Hausteinhaust...@google.com wrote: +1 Ray Could you contribute your implementation(s)? On Thu, Jun 11, 2009 at 12:51 PM, Joel Webber j...@google.com wrote: +1 Ray. Now here's the really tricky question. Is there any way we can take advantage of Javascript's for (x in y) { ... } syntax (and should we, given its spotty performance)? My intuition tells me that the only way we could use it would be through a callback, because there's nothing like .NET generators/yield in Javascript. On Wed, Jun 10, 2009 at 7:26 PM, Ray Cromwell cromwell...@gmail.com wrote: My take on this is that there is many places where I'd like to avoid JRE collections, but the basic JsArray is too much of a downgrade. I don't mind changing it to T if it doesn't effect performance cause then I
[gwt-contrib] Re: Optimize if statements to conditionals and boolean ops if possible
No problem... I haven't handled the common super-expression case (if (test) { return a; } else {return b; } - return test ? a : b), but that one should be pretty easy to tackle for a limited set of common super-expressions. On 11-Jun-09, at 5:53 AM, Joel Webber wrote: FWIW: http://code.google.com/p/google-web-toolkit/wiki/BooleanIfExpressionOptimization http://code.google.com/p/google-web-toolkit/wiki/IfToTernaryExpressionOptimization Thanks again for banging on these. I've been meaning to do it for ages... On Wed, Jun 10, 2009 at 9:11 PM, mmastrac.altern...@gmail.com wrote: Reviewers: scottb, Description: As suggested by scottb, we can optimize certain if statements to their boolean equivalents, ie: if (a()) {b()} else {c()} - a()?b():c() if (a()) {b()} - a()b() if (a()) {} else {b()} - a()||b() Please review this at http://gwt-code-reviews.appspot.com/36801 Affected files: dev/core/src/com/google/gwt/dev/js/JsStaticEval.java dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Optimize if statements to conditionals and boolean ops if possible
Both LGTM. Good catch, thanks. :) On 11-Jun-09, at 1:15 PM, Scott Blum wrote: Matt, Could you review these two follow-on patches? The second depends on the first. This is mostly non-functional cleanup to make things a little simpler to read. The only substantive change is this: Presently, if we have a CanBooleanEval that fails to resolve, we do nothing else. My second patch allows the failure case to fall through and check for more simplifications. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: More if-statement optimizations in JsStaticEval
SGTM. I'll start a new review with the remainder of the changes. On 10-Jun-09, at 2:16 PM, Scott Blum wrote: I thought I'd go ahead and commit what you have so far, if you don't object? On Wed, Jun 10, 2009 at 4:12 PM, mmastrac.altern...@gmail.com wrote: I'll update the patch with this change. While I'm at it, I may as well tackle this one too: if (test) {a()} else {b()} - test?a():b() On 2009/06/10 19:56:18, scottb wrote: LGTM. Want to point out that we can optimize some of these even better in cases where the nested code is an expression statement. http://gwt-code-reviews.appspot.com/33845/diff/1/2 File dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java (right): http://gwt-code-reviews.appspot.com/33845/diff/1/2#newcode37 Line 37: assertEquals(if(!a()){b()}, optimize(if (a()) { } else { b(); })); a()||b() http://gwt-code-reviews.appspot.com/33845/diff/1/2#newcode45 Line 45: assertEquals(if(a()){b()}, optimize(if (a()) { b() } else { })); a()b() http://gwt-code-reviews.appspot.com/33845 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: More if-statement optimizations in JsStaticEval
After I sent that message, I peeked into EqualityNormalizer which is basically pre-munging all the equality operators that compare against null to Cast.isNull() and Cast.isNotNull() as I described below. On 10-Jun-09, at 8:16 PM, Matt Mastracci wrote: That construct isn't a generically safe JS optimization, unless you have additional type info at the JS level to tell you what Java type the ifExpr was. I don't know for sure whether that information is available after the transition to JS (does SOYC make this available?). I believe that GenerateJavaScriptAST could be a bit smarter and not generate == null and != null for binary equality ops where the operand is known to be a reference type that isn't a string. One example failure case where null equality is not equivalent to binary coersion is the following: var a = false; if (a != null) { alert('blah'); } and var a = false; a alert('blah') BTW, this quick test shows that the problematic values are 0 (numeric zero), (the empty string), NaN and false: table script tests = [ [], {}, 0, null, undefined, , 0, null, undefined, NaN, NaN, true, false ] for (i = 0; i tests.length; i++) { document.write(trtd + ( + tests[i]) + /tdtd + (! tests[i]) + /tdtd + (tests[i] == null) + /td/tr); } /script On 10-Jun-09, at 5:20 PM, Scott Blum wrote: Ultimately that'd be great, whether that's a one step operation or a two-step. On Wed, Jun 10, 2009 at 7:16 PM, Ray Cromwell cromwell...@gmail.com wrote: Scott, do you mean replacing if(a != null) { expr; } with a expr? -Ray On Thu, Jun 11, 2009 at 4:56 AM, sco...@google.com wrote: LGTM. Want to point out that we can optimize some of these even better in cases where the nested code is an expression statement. http://gwt-code-reviews.appspot.com/33845/diff/1/2 File dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java (right): http://gwt-code-reviews.appspot.com/33845/diff/1/2#newcode37 Line 37: assertEquals(if(!a()){b()}, optimize(if (a()) { } else { b(); })); a()||b() http://gwt-code-reviews.appspot.com/33845/diff/1/2#newcode45 Line 45: assertEquals(if(a()){b()}, optimize(if (a()) { b() } else { })); a()b() http://gwt-code-reviews.appspot.com/33845 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: More if-statement optimizations in JsStaticEval
Yeah... I would love to have a single AST to represent both of the language states - many optimizations don't happen because we toss all the Java type info during the conversion to JS. For instance, you can't safely optimize this: if (blah != null) to this: if (blah) without knowing what type blah was at the beginning. In addition, a lot of optimizations would be a lot simpler to write (and some would just fall out of that structure) if we were dealing with a more abstract SSA version of the code, rather than a more direct AST. On 9-Jun-09, at 5:40 AM, Ray Cromwell wrote: This brings up the issue of whether or not there isn't someway to abstract some of these optimizations on the ASTs so that they can be shared by the Java and JS optimizers. I made patch along the same lines to the simplifier mirroring the Java simplifier. It seems like a lot of optimizations are being duplicated. -Ray On Tue, Jun 9, 2009 at 1:12 AM, mmastrac.altern...@gmail.com wrote: Reviewers: scottb, Description: I'm tackling another small issue on the JS side to get myself up to speed with the code (esp. the SOYC changes throughout) and help shake out all the cobwebs since my last set of patches :). This is a simple patch to improve the optimization of if statements. These items show up in compiled output, mostly in the generated exception handler code. It adds two extra optimizations: - Empty, but present else statements are pruned: if (x) {doSomething();} else {} - if (x) {doSomething();} - If statements with empty then conditions are inverted: if (x) {} else {doSomething()} - if (!x) {doSomething();} I also cleaned up my previous set of unit tests to use the clearer assertEquals() instead of assertTrue(x.equals(...)). Please review this at http://gwt-code-reviews.appspot.com/33845 Affected files: dev/core/src/com/google/gwt/dev/js/JsStaticEval.java dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java Index: dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java === --- dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java (revision 5519) +++ dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java (working copy) @@ -29,20 +29,36 @@ public class JsStaticEvalTest extends TestCase { + public void testIfWithEmptyThen() throws Exception { +assertEquals(a();, optimize(if (a()) { })); + } + + public void testIfWithEmptyThenAndElse() throws Exception { +assertEquals(if(!a()){b()}, optimize(if (a()) { } else { b(); })); + } + + public void testIfWithEmptyThenAndEmptyElse() throws Exception { +assertEquals(a();, optimize(if (a()) { } else { })); + } + + public void testIfWithThenAndEmptyElse() throws Exception { +assertEquals(if(a()){b()}, optimize(if (a()) { b() } else { })); + } + public void testLiteralEqNull() throws Exception { -assertTrue(optimize(alert('test' == null)).equals(alert(false);)); +assertEquals(alert(false);, optimize(alert('test' == null))); } public void testLiteralNeNull() throws Exception { -assertTrue(optimize(alert('test' != null)).equals(alert(true);)); +assertEquals(alert(true);, optimize(alert('test' != null))); } public void testNullEqNull() throws Exception { -assertTrue(optimize(alert(null == null)).equals(alert(true);)); +assertEquals(alert(true);, optimize(alert(null == null))); } public void testNullNeNull() throws Exception { -assertTrue(optimize(alert(null != null)).equals(alert(false);)); +assertEquals(alert(false);, optimize(alert(null != null))); } private String optimize(String js) throws Exception { Index: dev/core/src/com/google/gwt/dev/js/JsStaticEval.java === --- dev/core/src/com/google/gwt/dev/js/JsStaticEval.java (revision 5519) +++ dev/core/src/com/google/gwt/dev/js/JsStaticEval.java (working copy) @@ -35,6 +35,7 @@ import com.google.gwt.dev.js.ast.JsPrefixOperation; import com.google.gwt.dev.js.ast.JsProgram; import com.google.gwt.dev.js.ast.JsStatement; +import com.google.gwt.dev.js.ast.JsUnaryOperation; import com.google.gwt.dev.js.ast.JsUnaryOperator; import com.google.gwt.dev.js.ast.JsValueLiteral; import com.google.gwt.dev.js.ast.JsVars; @@ -348,8 +349,37 @@ block.getStatements().add(decls); } ctx.replaceMe(accept(block)); - } else if (isEmpty(thenStmt) isEmpty(elseStmt)) { -ctx.replaceMe(expr.makeStmt()); + } else { +boolean thenIsEmpty = isEmpty(thenStmt); +boolean elseIsEmpty = isEmpty(elseStmt); + +if (thenIsEmpty elseIsEmpty) { + ctx.replaceMe(expr.makeStmt()); +} else if (thenIsEmpty !elseIsEmpty) { + /* + * If the then block is blank, but the else
[gwt-contrib] Re: Suggestion for OOPHM
On 7-Jun-09, at 8:39 AM, John Tamplin wrote: Yes, the very thing you want for real apps (async so you can drop back to the event loop and let the browser respond while waiting on IO) is the very thing you can't have for OOPHM, since you have to be able to block the executing code in the browser until you get the response from the server (since you are emulating synchronous calls from JS-Java). Yeah... The XPCOM scripted component prototype I have uses the OPEN_BLOCKING (see https://developer.mozilla.org/en/NsITransport) flag when opening up the streams to the OOPHM server to ensure that all cross-channel calls are correctly synchronous. During the code, the JS IP is bouncing around within the JS component, never yielding to the page script itself. Since the browser is executing chrome-level code, the user doesn't see a slow script warning either, just a frozen browser (as expected). I don't forsee ever being able to do something like OOPHM without having some sort of per-browser native plugin or script component due to this single issue. At least on FF, those components could possibly be written in JS to minimize platform porting concerns. Even if browsers supported native JS continuations, you'd still have to ensure that no other JS was able to run (in-flight XMLHTTPRequest, event handlers, etc). Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Suggestion for OOPHM
On 6-Jun-09, at 6:24 PM, Mark Renouf wrote: Wow, I like it! This isn't as crazy as it sounds. After just watching the V8 talk from I/O, I've learned the JavaScript library is implemented in JavaScript (preloaded in a heap snapshot). The efficiency level they are hitting now makes this seem like a very sensible approach, especially for Chrome, etc. If the WebSocket standard ever materializes, it could be even better (and standards based), and act as a last-resort fallback on all platforms. I'm curious if it performs well enough for general use on Firefox? I suspect it's quite a bit slower right now. The XPCOM version never made it past the prototype stage (enough to connect to the server, handle LoadJSNI calls and just enough support for JS types to step through a couple of calls). I couldn't tell you what performance would be like, but with javascript.options.jit.chrome set to true, it should be running some fairly fast native code. BTW, one advantage of this XPCOM version is that it would work on both FF 3.0 and 3.5. The current OOPHM XPI fails on 3.5, as the Moz devs changed some of the JS type constants. JSVAL_VOID (the effective internal signature of the undefined value) is unfortunately an entirely different constant value in 3.5. Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Suggestion for OOPHM
While this subject is up... Has anyone considered writing the OOPHM client stub as a Java applet and using netscape.javascript.JSObject to deal with the JS references? While it wouldn't support direct field references like the current plugins do, the server-side Jsni class could rewrite those as method invocations (pass either a get, set or unary operator up to the server). Java itself could take care of listening for JSObject destruction: create a weak reference to the JSObject and put that in a reference queue. The plugin already deals with the Browser GC-JVM GC links, so this should just work (hah!). AFAIK, there a is limited amount of magic happening in OOPHM right now, basically boiling down to - field getter/setters - JSObject destruction - Invocation The only possible issue I can think of would be hitting that Window.enableScrolling() bug that killed the previous NPAPI plugin. On 5-Jun-09, at 9:37 AM, BobV wrote: An even-crazier setup would be that the locally-installed plugin is just a sled for downloading the actual plugin guts from the server. This way, a single plugin installation could work with different versions of the OOPHM host code. -- Bob Vawter Google Web Toolkit Team --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Suggestion for OOPHM
On 5-Jun-09, at 10:08 AM, Piotr Jaroszyński wrote: 2009/6/5 Matt Mastracci matt...@mastracci.com: While this subject is up... Has anyone considered writing the OOPHM client stub as a Java applet and using netscape.javascript.JSObject to deal with the JS references? Please no java applets. They only recently started working on 64bit linux and I woudn't call them stable. Fair enough.. :) I haven't had much experience with applets on OSX, so I'm not sure what the state is on this platform either. I've also been playing with a 100% Javascript version of the OOPHM client stub as well, but it's been put on hold now that I've fixed the bug in the binary component that was stopping me from instantiating it from chrome:// documents. It basically uses GWT and some XPCOM bindings that I've generated for our product previously to implement the client side of things. It might be a good alternative to having a binary component for FF, which is by far the browser that requires the most cross-platform compilation. It's no more than a proof-of-concept right now, but if there's interest from others I can share the code and/or work on completing it. Since it's written using GWT, it's just a matter of porting the current server-side BrowserChannel over. Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Email address in from field @ gwt-code-reviews
I've posted a couple of patches to the codereviews site, but I noticed that it's using my main google account as the from email (mmast...@gmail.com ) instead of my mailing list subscription address (matt...@mastracci.com). Any ideas how I might be able to set my from address on the codereviews site to use the correct address, or allow those messages to come through to this list? I can't get Groups to allow me to subscribe with both addresses, and mail sent from the wrong address ends up in the moderation queue. :) Thanks, Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Eclipse Plugin and OSX woes
Jason, Thanks for the idea, it works well. I blogged the full instructions below and included the final Python script I used to wrap the Java executable. I've now managed to deploy an AppEngine project that uses a 1.6 JVM to run (and is compatible with 1.6-level-compiled JAR files) along with the supporting GWT code. http://grack.com/blog/2009/04/19/the-final-word-on-google-eclipse-plugin-osx-crashes/ 8 #!/usr/bin/env python import sys import os print sys.argv cmd = os.path.dirname(sys.argv[0]) + '/java_wrapped' args = ['', '-XX:CompileCommand=exclude,org/eclipse/core/internal/dtree/ DataTreeNode,forwardDeltaWith', '-XX:CompileCommand=exclude,org/eclipse/jdt/internal/compiler/ lookup/ParameterizedTypeBinding,init', '-XX:CompileCommand=exclude,org/eclipse/jdt/internal/compiler/ lookup/ParameterizedMethodBinding,init'] args.extend(sys.argv[1:]) print cmd print args print os.execv(cmd, args) 8 On 17-Apr-09, at 12:41 PM, Jason Parekh wrote: Hey Matt, Unfortunately, it's not currently possible to specify arguments to the JVM that runs the GWT compile. We're aware of the demand for this feature though, so expect it in a future release. As an absolute workaround, could you rename your java binary and create a shell script in its place that launches the real java binary with whichever args you want (prepended to the args given to the shell script)? jason On Fri, Apr 17, 2009 at 2:34 PM, Matt Mastracci matt...@mastracci.com wrote: I'm running into the same JVM crash under Eclipse that I was running into from Ant a few weeks ago (http://grack.com/blog/2009/04/14/gwt-16-crashes-and-a-fix/ ) while trying to deploy a test AppEngine+GWT project. The output from the compiler is pretty much: Compiling module ... Invalid memory access of location rip=01160767 Any ideas where the Eclipse Plugin gets the JVM and the JVM arguments to run to GWT portion of the compile? I tried adding the JIT overrides to the workspace JRE default JVM properties, but those don't seem to get picked up. -XX:CompileCommand=exclude,org/eclipse/core/internal/dtree/ DataTreeNode,forwardDeltaWith -XX:CompileCommand=exclude,org/eclipse/jdt/internal/compiler/lookup/ ParameterizedTypeBinding,init -XX:CompileCommand=exclude,org/eclipse/jdt/internal/compiler/lookup/ ParameterizedMethodBinding,init The only argument I can see in the process list is -Xmx512m. Thoughts/ideas? Thanks, Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Relaxing constraints on GWT.create()
If you wanted to be guaranteed order-of-operations safety, you could pass a factory into the method instead of the object itself and replace the GWT.create() calls with a create() method on the factory. AFAICT, this would have the same sequence of side-effects as GWT.create() would. Bonus feature: In the case where only one class constant is ever passed into this method, the compiler should be able to replace the virtual call with the new MyService() expression (and possibly inline the whole @GwtCreate function as well). For instance, something like the following pseudocode: interface GwtCreateFactory { T T create(); } class MyService__GwtCreateFactory implements GwtCreateFactory { @SuppressWarnings(unchecked) T T create() { return (T)new MyService(); } } public class OAuth { @GwtCreate // method must be static, class parameter must be final public static S, T extends RemoteServiceS S withSignature(final GwtCreateFactoryT service) { // GWT.create with non-literal ONLY allowed // if enclosing method is @GwtCreate and // variable statically resolvable to literal param S async = service.create(); ((ServiceDefTarget)async).setRequestBuilderCallback(new OAuthRequestBuilderSigner()); return async; } } OAuth.withSignature(new MyService__GwtCreateFactory()).method1(arg1, arg2, asyncCallback); On 13-Mar-09, at 12:09 AM, Ray Cromwell wrote: One concern I have is order of operations, since the GWT.create() is implicitly hoisted from its callsite, and I could see some crazy thing where code in the method depends on the deferred binding not being initialized early. It's kinda like the clinit() hoisting problem. I say we just define some rules that allow hoisting within a method body, otherwise, you'll have to inline the whole method at the callsite (yuck!) -Ray On Thu, Mar 12, 2009 at 10:55 PM, Matt Mastracci matt...@mastracci.com wrote: +1 for this implementation. This is a lot clearer than a class - implementation lookup map or inlining the whole method at each call site. As long as the bytecode is rewritten in hosted mode to match the expected order of operations, there shouldn't be any surprises at compile time. Could this cause issues with anyone running GWT.create() in server- side code? Does that even work today? On 12-Mar-09, at 10:23 PM, Ray Cromwell wrote: BTW, My proposed implementation is to rewrite these methods changing the literal parameter to the result of invoking GWT.create() at the call site, e.g. interface MyService extends RemoteServiceMyServiceAsync { ... } // example call OAuth.withSignature(MyService.class).method1(arg1, arg2, asyncCallback); public class OAuth { @GwtCreate // method must be static, class parameter must be final public static S, T extends RemoteServiceS S withSignature(final ClassT service) { // GWT.create with non-literal ONLY allowed // if enclosing method is @GwtCreate and // variable statically resolvable to literal param S async = GWT.create(service); ((ServiceDefTarget)async).setRequestBuilderCallback(new OAuthRequestBuilderSigner()); return async; } } after rewrite at callsite: Object async = GWT.create(MyService.class); OAuth.withSignature(async).method1(arg1, arg2, asyncCallback); rewritten method: public class OAuth { @GwtCreate // method must be static, class parameter must be final public static S, T extends RemoteServiceS S withSignature(Object asyncInstance) { //S async = GWT.create(service); replaced with instance S async = (S)asyncInstance; ((ServiceDefTarget)async).setRequestBuilderCallback(new OAuthRequestBuilderSigner()); return async; } } This doesn't handle generator override or extra params, but it's a start and could work with minimal changes to ReplaceRebinds. -Ray On Thu, Mar 12, 2009 at 7:17 PM, Ray Cromwell cromwell...@gmail.com wrote: Yeah, it's mostly the same as was discussed in the past. I just decided to resurrect the idea given that 1.6 is almost shipped to ensure it has a good chance of making it into the next version. -Ray On Thu, Mar 12, 2009 at 5:49 PM, Ian Petersen ispet...@gmail.com wrote: Seems like this might be related to http://code.google.com/p/google-web-toolkit/issues/detail?id=2243 I like the idea. Ian --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Relaxing constraints on GWT.create()
+1 for this implementation. This is a lot clearer than a class - implementation lookup map or inlining the whole method at each call site. As long as the bytecode is rewritten in hosted mode to match the expected order of operations, there shouldn't be any surprises at compile time. Could this cause issues with anyone running GWT.create() in server- side code? Does that even work today? On 12-Mar-09, at 10:23 PM, Ray Cromwell wrote: BTW, My proposed implementation is to rewrite these methods changing the literal parameter to the result of invoking GWT.create() at the call site, e.g. interface MyService extends RemoteServiceMyServiceAsync { ... } // example call OAuth.withSignature(MyService.class).method1(arg1, arg2, asyncCallback); public class OAuth { @GwtCreate // method must be static, class parameter must be final public static S, T extends RemoteServiceS S withSignature(final ClassT service) { // GWT.create with non-literal ONLY allowed // if enclosing method is @GwtCreate and // variable statically resolvable to literal param S async = GWT.create(service); ((ServiceDefTarget)async).setRequestBuilderCallback(new OAuthRequestBuilderSigner()); return async; } } after rewrite at callsite: Object async = GWT.create(MyService.class); OAuth.withSignature(async).method1(arg1, arg2, asyncCallback); rewritten method: public class OAuth { @GwtCreate // method must be static, class parameter must be final public static S, T extends RemoteServiceS S withSignature(Object asyncInstance) { //S async = GWT.create(service); replaced with instance S async = (S)asyncInstance; ((ServiceDefTarget)async).setRequestBuilderCallback(new OAuthRequestBuilderSigner()); return async; } } This doesn't handle generator override or extra params, but it's a start and could work with minimal changes to ReplaceRebinds. -Ray On Thu, Mar 12, 2009 at 7:17 PM, Ray Cromwell cromwell...@gmail.com wrote: Yeah, it's mostly the same as was discussed in the past. I just decided to resurrect the idea given that 1.6 is almost shipped to ensure it has a good chance of making it into the next version. -Ray On Thu, Mar 12, 2009 at 5:49 PM, Ian Petersen ispet...@gmail.com wrote: Seems like this might be related to http://code.google.com/p/google-web-toolkit/issues/detail?id=2243 I like the idea. Ian --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: installing code at global scope
Lex, Have you tried using the string constructor for Function()? I believe that it creates a function whose lexical scope is bound to the top- level, no matter where it is executed. script var a = 2; function x() { var a = 3; return new Function(alert(a); a = 4;); } x()(); alert(a); function y() { var a = 10; x()(); } y(); /script This alerts 2, 4, 4 in Firefox, Safari, Opera and IE6. On 5-Mar-09, at 1:19 PM, Lex Spoon wrote: For possible amusement, I spent half a day yesterday spelunking into the world of various ways to install code in a web browser. Details are here: http://lexspoon.blogspot.com/2009/03/many-scopes-of-javascripts-eval.html My initial idea to use window.eval turns out to be terribly non-portable: it only evaluates at window scope on Firefox. Instead, I'm thinking to use the following code to install newly downloaded code: if (window.execScript) { window.execScript(script) } else { var tag = document.createElement(script) tag.type = text/javascript tag.text = script document.getElementsByTagName(head).item(0).appendChild(tag) } The first branch is for window.execScript, which is available on IE and, of all things, Chrome. They are such similar browsers, you know. The second branch works on all browsers, but it's ugly enough that I didn't want it to be used all the time. Maybe that's silly, and only the second branch should always be used. Any thoughts or better ideas? Lex --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: installing code at global scope
I think this one is deprecated. It was removed for a short period of time in FF 3.1, then restored in a slightly different form: Removed in: https://bugzilla.mozilla.org/show_bug.cgi?id=442333 Caused a bug in: https://bugzilla.mozilla.org/show_bug.cgi?id=457068 Restored (in a different form) in: https://bugzilla.mozilla.org/show_bug.cgi?id=446026 I believe the new form lets you clobber the scope chain during (but not beyond) the eval() call, somewhat like Firefox's evalInSandbox() for chrome code. On 5-Mar-09, at 3:20 PM, Ray Cromwell wrote: There is also the magic eval() method in Firefox which allows an additional parameter to be specified as the context (see http://ajaxian.com/archives/evalfooa-objfn-how-you-arent-private-in-firefox) e.g. eval(script, $wnd); -Ray On Thu, Mar 5, 2009 at 2:10 PM, Matt Mastracci matt...@mastracci.com wrote: Lex, Have you tried using the string constructor for Function()? I believe that it creates a function whose lexical scope is bound to the top- level, no matter where it is executed. script var a = 2; function x() { var a = 3; return new Function(alert(a); a = 4;); } x()(); alert(a); function y() { var a = 10; x()(); } y(); /script This alerts 2, 4, 4 in Firefox, Safari, Opera and IE6. On 5-Mar-09, at 1:19 PM, Lex Spoon wrote: For possible amusement, I spent half a day yesterday spelunking into the world of various ways to install code in a web browser. Details are here: http://lexspoon.blogspot.com/2009/03/many-scopes-of-javascripts-eval.html My initial idea to use window.eval turns out to be terribly non-portable: it only evaluates at window scope on Firefox. Instead, I'm thinking to use the following code to install newly downloaded code: if (window.execScript) { window.execScript(script) } else { var tag = document.createElement(script) tag.type = text/javascript tag.text = script document.getElementsByTagName(head).item(0).appendChild(tag) } The first branch is for window.execScript, which is available on IE and, of all things, Chrome. They are such similar browsers, you know. The second branch works on all browsers, but it's ugly enough that I didn't want it to be used all the time. Maybe that's silly, and only the second branch should always be used. Any thoughts or better ideas? Lex --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: installing code at global scope
On 5-Mar-09, at 4:53 PM, Lex Spoon wrote: On Thu, Mar 5, 2009 at 5:10 PM, Matt Mastracci matt...@mastracci.com wrote: function x() { var a = 3; return new Function(alert(a); a = 4;); } I hadn't thought of that! Unfortunately, the code in question has definitions like function foo() { ... } that are intended to end up defined at global scope. Joel suggests that it would work to rearrange the code to look more like foo = function() { ...} or even window.foo = function() { ...}. I agree, but that means the compiler would need to be coaxed into generating this alternate code. It ultimately needs to, anyway, for supporting the cross-site linker, but I was hoping to avoid getting into that right now. Ah yeah - any of the new definitions in the body of Function end up in the Function's private scope, even though the parent scope of the function body is the global one. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: RR : Implement web-mode stack traces and symbol map files
Bob, Changes look really good. Some review notes: This code will terminate early if you have two anonymous functions in your call stack (possible for some DOM stack traces), since both will have name == anonymous: +// Avoid infinite loop: caller is not an activation record +if (seen['_' + name]) { + break; +} else { + seen['_' + name] = 1; + callee = callee.caller; +} Re: the JSON string escaping function. I filed a bug a while back where unicode line separators would trip up RPC because they weren't being escaped: http://code.google.com/p/google-web-toolkit/issues/detail?id=2270q=json According to my tests, Firefox 3, Opera 9 and Safari 3 all require \u2028 and \u2029 to be escaped. I haven't tested with IE for a while, but it may have additional characters that require escaping on top of those. Here's my test script: script for (i = 0x0; i = 0x; i++) { try { if (eval(\ + String.fromCharCode(i) + \) != String.fromCharCode(i)) document.write(i.toString(16) + : not equal!br); } catch (e) { document.write(i.toString(16) + : + e + br); } } /script On 17-Feb-09, at 3:02 AM, BobV wrote: I've created a branch to track future changes to this patch. svn merge -r4761:HEAD http://google-web-toolkit.googlecode.com/svn/changes/bobv/web_mode_stack_traces_r4761 Changes from previous patch: - Added web-mode stack-trace inference for JavaScriptExceptions with additional methods in StackTraceCreator.Collector. This only works for Mozilla and Opera. Other browsers will return zero-length arrays for JavaScriptException.getStackTrace(). - Fixed extractName() to be more robust. - Fixed loop condition in Collector.collect() and added a Mozilla/Opera variant to use stack inference to improve accuracy. - The symbol map no longer attempts to de-staticify static methods. This caused a map collision when a polymorphic-dispatch version of a methods exists alongside a static-dispatch version. -- Bob Vawter Google Web Toolkit Team --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: RR : Implement web-mode stack traces and symbol map files
Bob, We've been doing the same thing for a while using a slightly different method. Some notes from our implementation: 1. The callee chain represents functions, rather than activation records as you'd expect. If you call a method re-entrantly, you'll end up in an infinite loop (a.callee - b.callee - c.callee - a.callee). Our implementation uses a loop counter to prevent this from running away, but a better implementation would be testing against a set of functions that have already been seen. 2. e.stack works a lot better in Firefox, since methods that appear twice in the stack don't cause the stack trace to terminate early. 3. Argument information for non-reentrant functions is pretty reliable across browsers. It might be worth capturing the shape of parameters where the value is available (ie: [number], [HTML element], etc.) 4. Opera's caller property is unreliable in GWT web mode code and the caller chain peters out after a few iterations for some unknown reason. It has its own stack trace property on exceptions, somewhat like the one Firefox offers. On 13-Feb-09, at 11:04 AM, BobV wrote: The attached patch implements web-mode stack traces and the ability for the compiler to emit a per-permutation symbol map file during the compile. An example of this map for the DynaTable sample is also attached. User-visible changes: - CompilationResult has a getSymbolMap() method that will return a map of obfuscated identifiers to JSNI-style identifiers for classes, methods, and fields. - A SymbolMapsLinker has been added to emit this data, which can be enabled via add-linker name=symbolMaps / - Throwable now implements fillInStackTrace(), which is called in its instance initializer. - The StackTraceElements returned from getStackTrace() only contain useful data for getMethodName(), which returns the JS function name. - GWT.getPermutationStrongName() has been added to distinguish between permutations of a module. - A utility class, HttpThrowableReporter, will POST a JSON-formatted representation of a Throwable back to the server. It is intended to be used as an UncaughtExceptionHandler. - A JsonUtils class is added to user.client. It doesn't have all the methods that you'd want in such a class, but we've been meaning to rework our JSON support at some point, and this seems like the natural place to put an overlay-type-based implementation. - If you run web-mode JUnit tests with -style PRETTY mode, you'll get not-unreasonable stack traces in your logs. Implementation details: - Linkers must now add a top-level variable $strongName to the emitted JS. - StackTraceCreator creates the stack trace by crawling arguments.callee.caller. I'm pretty sure this works in all browsers, but I don't presently have access to IE to test this. The class is structured with an inner class that can be used as a deferred-binding hook point if it's necessary. - As long as Throwable's instance initializer is inlined into each exception's constructors (since it's a one-liner invocation of fillInStackTrace), the top-level stack frames can be used to accurately determine the type of Throwable being thrown. - The symbol maps take advantage of the limited numbed of lexical scopes used in GenerateJavaScriptAst, that all methods/functions are declared in one scope, and that all fields are declared in the object scope. Future work: - Write a resymbolizer servlet to receive the payloads sent by HttpThrowableReporter. We do need to decide the policy/implementation details of the GWT compiler emitting resources that are intended to be available on the server's classpath. - @bruce, the symbol map information can be used for more efficient RPC per your earlier emails Diffstat: dev/core/src/com/google/gwt/core/ext/linker/CompilationResult.java | 22 15 +7 - 0 ! dev/core/src/com/google/gwt/core/ext/linker/impl/ SelectionScriptLinker.java | 11 5 + 6 - 0 ! dev/core/src/com/google/gwt/core/ext/linker/impl/ StandardCompilationResult.java | 4333 +10 -0 ! dev/core/src/com/google/gwt/core/linker/IFrameLinker.java |4 3 + 1 - 0 ! dev/core/src/com/google/gwt/core/linker/SingleScriptLinker.java |3 3 + 0 - 0 ! dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java | 118 118 + 0 - 0 ! dev/core/src/com/google/gwt/core/linker/XSLinker.java |2 2 + 0 - 0 ! dev/core/src/com/google/gwt/dev/PermutationResult.java |6 6 + 0 - 0 ! dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java | 31 27 +4 - 0 ! dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java | 54 48 +6 - 0 ! user/src/com/google/gwt/core/Core.gwt.xml | 10 6 + 4 - 0 !
[gwt-contrib] Re: RR : Implement web-mode stack traces and symbol map files
One other minor item I just noticed: in IE, an anonymous function's toString output has no spaces (function(){} vs. function (){} in other browsers), so the below assertion and associated function will fail: + static String extractName(String fnToString) { +assert fnToString.startsWith(function ); On 13-Feb-09, at 12:26 PM, BobV wrote: @mmastrac, Thanks for the data. I think that I should add an override to JavaScriptException to handle non-java exceptions in those browsers that do have e.stack or equivalent and retain some kind of caller chain for java-dervied exceptions. -- Bob. (Android) On Feb 13, 2009 1:25 PM, Matt Mastracci matt...@mastracci.com wrote: Bob, We've been doing the same thing for a while using a slightly different method. Some notes from our implementation: 1. The callee chain represents functions, rather than activation records as you'd expect. If you call a method re-entrantly, you'll end up in an infinite loop (a.callee - b.callee - c.callee - a.callee). Our implementation uses a loop counter to prevent this from running away, but a better implementation would be testing against a set of functions that have already been seen. 2. e.stack works a lot better in Firefox, since methods that appear twice in the stack don't cause the stack trace to terminate early. 3. Argument information for non-reentrant functions is pretty reliable across browsers. It might be worth capturing the shape of parameters where the value is available (ie: [number], [HTML element], etc.) 4. Opera's caller property is unreliable in GWT web mode code and the caller chain peters out after a few iterations for some unknown reason. It has its own stack trace property on exceptions, somewhat like the one Firefox offers. On 13-Feb-09, at 11:04 AM, BobV wrote: The attached patch implements web-mode stack traces and t... web_stack_traces_r4689_r2 .patch15CD200D012CAACC790C8430C40192E8_sybolMap.properties.gz --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---