[gwt-contrib] idea: i18n dynamic templating ? (like wordpress), feedback
Please some feedback on the following i18n dynamic templating idea: 1) Have text in separated files like xml (or json). 2) Have all html/css in html pages. All wil recognize this approach, it's no rocket science, but I miss it. I noticed there are some ideas/projects like dynamicUiBinder out there that come close, but not enough. I think there also bigger frameworks that use gwt as frontend that have something like this (but I don't want to use the whole framework). Both 1) and 2) are lazy loaded from the backend when needed and merged to create the html snippet/page. Reasons? a) High productivity: The web designer/developer can focus entirely on creating the html/css pages/snippets. I always get frustrated that I have to do too much css/html stuff as a gwt developer while others can do this much better. b) Flexibility: Changing some html/text without having to change the gwt code (- rebuild/deploy/test). Existing Cms tools/frameworks can be used to update the text and html/css and publish the updated files that are then used by the existing gwt code. c) Dynamic multi language support: all texts are contained in separated files. By starting up the app with another parameter value (through url query param or in in the index.html), another language files are loaded. I think it's comparable with the Wordpress approach: you download a wp template and put any text in your want through the wp admin. Currently I have half this approach (using it for years now): all texts come from cms xml files (managed by hand or in the future a admin/cms tool). This works well, all xml files are lazy loaded when needed. They currently contain a bunch of html that is further decorated by gwt code (adding buttons, form fields, etc..). My main reason is that I want to boost productivity and let every developer do what he does best. Currently I find that hard, as css/html isn't well separated such that it can be easily used by html/css/web developers that aren't gwt developers. At the end of the day, I am doing too much html/css that I don't want to do as others can do that much better/faster. Nowadays it's common to do the html/css abroad much cheaper (and better), but that's difficult when using gwt (did it several times). The way of work: 1) A html/css expert take the design input (photoshop/sketch/etc...) and create the html pages/snippets. 2) The html files are further decorated by the gwt developer such that can be decorated/used by his gwt code: replacing the text by labels; putting the text in the cmsl xml files; adding id's to further decorate it by the gwt code. The idea is that the html snippets/files will stay the main working doc for both the gwt and html/css developer, such that it's directly used by both: that makes it easy to make changes and directly use them. Currently, html files are often translated to some html snippet (UiBinder) that is usable for the gwt developer, but not anymore for the html/css developer, that leads to misunderstanding/bugs/delays/frustration/etc... Please your feedback? (how do others solve this problem currently ?) I want to build the other half somewhere in the coming months. How does this fall in place with the upcoming gwt releases (web components approach) ? -- You received this message because you are subscribed to the Google Groups GWT Contributors group. To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/fe44aa4b-f675-474c-bbe7-802423363ccd%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [gwt-contrib] Re: idea: i18n dynamic templating ? (like wordpress), feedback
@Jens: thanks for your feedback. I looked at it. I like the component-based annotation approach. It sure gives me inspiration. It would be nice if this templating mechanism can be used independently of the rest of the platform (haven't looked at it yet), and that it's flexible to extend it (It extends Widget which for me is obsolete, don't use it anymore except for the root) -- You received this message because you are subscribed to the Google Groups GWT Contributors group. To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/CABzbGkL-%3DUSgNodYMKi2829iZwmfcGqQbeFMmS2dj-MuBrh0dw%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
[gwt-contrib] Re: Would you like to add a gwtproject.com search input for only the gwtproject site?
What do you think of having a google custom search for the gwtproject site, which searches only that site? +1 -- http://groups.google.com/group/Google-Web-Toolkit-Contributors --- You received this message because you are subscribed to the Google Groups GWT Contributors group. To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [gwt-contrib] widget interfaces
FYI: the IsElement interfaces corresponds to issue 7497: http://code.google.com/p/google-web-toolkit/issues/detail?id=7497 On Fri, Jun 7, 2013 at 5:03 AM, Stephen Haberman step...@exigencecorp.comwrote: If nobody else has any other concerns, I recommend you to start with an example interface to get early feedback and iterate from there. So, I was going to start with just one, but copy/pasting them over and changing the package name was pretty easy, so: https://gwt-review.googlesource.com/#/c/3231/ I only changed a few of the widgets to implement their IsXxx counterpart (Button, ComplexPanel, AbsolutePanel)--all pretty trivial. I didn't realize this before, but I ended up slipping IsElement in here because it's part of the extended IsWidget interface. There are some other IsElement related things, like having IsElement extend HasStyle and HasText that I'm flexible on, but are handy IMO. Very much request for comment sort of state. Anyone feel free to respond here or in the code review. - Stephen -- http://groups.google.com/group/Google-Web-Toolkit-Contributors --- You received this message because you are subscribed to a topic in the Google Groups GWT Contributors group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-web-toolkit-contributors/odoaoi1s7N0/unsubscribe?hl=en-US . To unsubscribe from this group and all its topics, send an email to google-web-toolkit-contributors+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors --- You received this message because you are subscribed to the Google Groups GWT Contributors group. To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [gwt-contrib] Re: widget interfaces
Let me see if I understand this Type 1/2 discussion correctly: yes, the short Has* interfaces are a bit of a pain: awkward names, mass of small interfaces, must-use of class generics if you need to more Has* interfaces. Buttt, they make them very nice manageable through general Utils* methods.. For example: My root IsWidget interface: public interface FlexWidget extends IsWidget, AsIsWidget, HasTitle, HasVisible, HasStyleName, HasEnabled, HasEnsureDebugId, HasEventManagement {} And The HasStyleName look like: public interface HasStyleName extends HasAddStyleName { void setStyleName(final String style); String getStyleName(); void removeStyleName(final String style); } --- In the UtilsWidget class I have all kind of methods like: public static W extends HasAddStyleName W addStyle(final W widget, final String styleName) { if (isNotNull(widget)) { widget.addStyleName(styleName); } return widget; } public static W extends HasStyleName W setStyle(final W widget, final String styleName) { if (isNotNull(widget)) { widget.setStyleName(styleName); } return widget; } public static W extends HasEnsureDebugId W ensureDebugId(final W widget, final String debugId) { if (isNotNull(widget)) { widget.ensureDebugId(debugId); } return widget; } This makes coding safe, short and easy to understand/maintain (fluent coding)... Concerning implementation: If you create a Is* widget like IsButton you have to think about when to create the contains Widget variant like the Button class. I want to do this as lazy as possible... So the question is, if you call IsButton.addStyle(String), do you forward this directly to the contained Button or do you buffer it? I buffer it, such that I can run these operations in unit tests (not GWTTestCase... -- http://groups.google.com/group/Google-Web-Toolkit-Contributors --- You received this message because you are subscribed to the Google Groups GWT Contributors group. To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [gwt-contrib] Re: widget interfaces
The simpler thing than buffering is just to have a StubButton, e.g.: A, how could I forget ;)... I just remember the Stubs* Widgets in your gitHub ;) But is this even needed ? If you use a template mechanism it might not be needed. The template is created during setStyle() and other operations and only used in GWT client mode when the underlying Widget is created... -- http://groups.google.com/group/Google-Web-Toolkit-Contributors --- You received this message because you are subscribed to the Google Groups GWT Contributors group. To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [gwt-contrib] Re: widget interfaces
So, my point: Is the purpose of the IsButton *only* to be an interface for com.google.gwt.user.client.ui.Button? Good point, when submitting my prev post, I was just think about: What problem is being solved here? Or What is improved ? Maybe good to summarize the list of goals and then work on them (like the white papers proposals in the gwt wiki). Either we have a backward compat problem I would start a separate IsWidget hierarchy. That makes it easier and overcomes all kind of conflicts and pain... People can then to decide them self if they want to use them.. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors --- You received this message because you are subscribed to the Google Groups GWT Contributors group. To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[gwt-contrib] Re: IsElement interface with asElement() method just like IsWidget?
Related issue and discussion: 7497http://code.google.com/p/google-web-toolkit/issues/detail?id=7497 -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] IsElement interface with asElement() method just like IsWidget?
Hi, Do you think about an IsElement interface with one method: asElement(), just like IsWidget interface. I like to add this as Enhancement Issue, but like to hear if it's worth doing so? I use it in some cases in my own code, where possible, to be able to unit test more. I am happy about it. - Ed -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Store IsWidget instances in Panel instead of Widget?
Thanks, for the clear explanation. I wasn't aware of this. If that's how it was designed, I understand it, but I don't think this is well explained in the documentation and I hope most GWT developers know this. And why not extend this functionality to the way I use it so it might become more useful? - Ed On Feb 28, 4:22 am, Stephen Haberman step...@exigencecorp.com wrote: public Widget asWidget() { return getEnsureUiWidget(); } You shouldn't be doing this. asWidget wasn't added to allow lazy initialization of widgets. It was added so that dummy widgets can pretend to be widgets--but only in tests. When not testing, the assertion: assert widget.asWidget() == widget Should always pass. In other words, the only implementations of asWidget should ever be: A) In a real widget: public Widget asWidget() { return this; } B) In a stub/mock/fake widget: public Widget asWidget() { throw new RuntimeException(no, i'm not a real widget!); } While your use of asWidget is creative, it's not at all the intent, and so it's not surprising you're seeing odd results. - Stephen -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Store IsWidget instances in Panel instead of Widget?
Why not store the IsWidget instances as children in the Panel, instead of the contained Widget? At this moment Panels contain a WidgetCollection instance that contains Widget instances. Why not use store the IsWidget instances. I don't think this breaks anything as Widget implements IsWidget. I think this improves the lazy behavior of Widgets. I love the IsWidget interface as it improves the lazy creation of widgets, testing, and result in the creation of widget interfaces. However, at the moment that you want to store it in a panel, you have to store the contained widget, which leads to nasty situations. Example: I have a widget that I add to some Panel: class TitleWidget implements IsWidget, HasText {} and the implementation (uses the UiBinder): class TitleWidgetUi implements LineTitle { ... ... public Widget asWidget() { return getEnsureUiWidget(); } private Widget getEnsureUiWidget() { if (this.uiWidget == null) { // lazy creation this.uiWidget = GWT.TitleWidgetUiBinder create(TitleWidgetUiBinder.class).createAndBindUi(this); } return this.uiWidget; } } Usage: Panel panel = new FlowPanel(); panel.add(new TitleWidget(createTitleText()); // panel will store the contained widget and not the TitleWidget instance private String createTitleText() { return Logged in member: + getMemberName()); } As you can see, the title widget contains some member name. If his member name changes, I iterate through the widgets contained in Panel and in case it implements HasText, I update the title text. Code: for (Widget widget: panel.iterator()) { if (widget instanceof HasText) { ( (HasText) widget).setText(createTitleText()); } } However, this will never work as you would expect as the panel will contain the Widget contained in the created TitleWidget instance and not the TitleWidget instance itself. And the contained widget isn't implementing HasText. The above situation is common I think as the member name is contained in a global data model and I don't allow listeners to subscribe them self because of possible memory leaks. Memory leaks can easily occur when widget are added and removed and don't remove their listener. This was what happened in the past, so I changed this (we don't have weak listeners in gwt/javascript like in swt). So a changed member name is pushed on the event bus, controllers will receive it and further distribute it to the potential interested widgets. I might react: Stupid that a widget doesn't remove his listener when removed. Of course, this would be the perfect case, but in complex situations it's easily forgotten and almost unavailable (my experience) Work around: let LineTitleUi extend Composite, such that Panel will store it directly and not the contained widget. but that then you will loze the lazy behavior and you can't test it anymore outside of GWT. Especially this latter one is important and important result of the IsWidget interface.. In this case the IsWidget loses his value and could also be removed.. What do you think ? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Multiple leftover fragments with a tree of code split points?
Please some advice on the following. Sorry for reposting the question below, I tried the GWT user forum but I think I have better luck here: --- I am about to migrate 3 gwt app's to one gwt app. All gwt app's contain code split points, and I want to connect them with 3 code split points. I am a bit concerned about the left over fragment. From the documentation I understand that I only have one leftovers code fragment, which isn't very ideal I think in my situation. The code split points after migration: main app 1 split point: login app 1a, 1b, 1c, .. split points in the login app. 2 split point: profile app 2a, 2b, 2c, .. split points in the profile app. 3 split point: declare app 3a, 3b, 3c, .. split points in the declare app. I am afraid that my leftover code fragment becomes rather large, where I would love to have several leftover fragments that belong only to 1), 2), or 3). Is that possible? How does gwt deal with this? From the documentation I read that code are put in the leftover code fragment if it's not unique to one split point. Ok, I understand that but in my case it's unique to the parent split point. Example: I have leftover code that is used in 1a and 1b split points, but is unique to 1), so I would guess that 1) has his own unique leftover. Can somebody please give some details on this, on how gwt deals with these kind of nested split point situations? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
I couldn't hold back investigating a bit more. Like described in my last post, the timeout always occurred/started in a GWTTestCase class that contained two test cases that involve RPC calls. I did split up these test cases such that they have their own GWTTestCase class, and the timeout appearantly disappeared as I have seen it now for a week. All tests run fine now. Any idea how/why this is ? After all the debugging/work I get the feeling that there exists some deep hidden bug causing this timeout. .. Ed On Oct 13, 2:40 pm, Ed post2edb...@gmail.com wrote: I give up for now :(... This issue is getting me against the roof... :( Even with remote debugging it all go well But let's not forget that the error only occurs sometimes: about 50% of the time and mostly during the day when I run the build manually when the server is more busy. During the night when the build server isn't doing much, most of the time thetimeoutexception doesn't occur. Almost always the exception occurs in atestclass (extending GWTTestCase) that contains more then onetest. As far as I can see, it never happens intestclasses with only onetestmethod... So it seems that more tests in one GWTTestCase class take more time and in someway triggers thetimeoutexception... Also, in case thetimeoutexception occurs, the logging indicates that the GWT servlet GWTShellServlet is correctly informed, but still the exception occurs... For now, I disabled these GWTtestcase that need the backend (through RPC) as I can't work with this unpredictable behavior. On Oct 5, 4:56 pm, Ed post2edb...@gmail.com wrote: running thetestin your continuous build environment with remote debugging enabled and attaching to it with a debugger to see what is going on. Thanks again. John I did that already but will do it again now that I have a better understanding of the GWT Junit code. (I only have to use some tricks to attach the remote debugger correctly ...) On Oct 5, 4:24 pm, John Tamplin j...@google.com wrote: On Tue, Oct 5, 2010 at 10:12 AM, Ed post2edb...@gmail.com wrote: I found the servlet you meant: JUnitHostImpl I see that the url that touches this servlet is correctly forwarded by the proxy and received by this servlet when debugging in Eclipse: The url that touches it: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost (also appears in the logging below) However, when it's running during the nightly build and fails, I's hard to find out what went wrong as the this servlet doesn't contain debug/trace logging. It would be nice to see the path of execution in the logging such that I can see why the servlet isn't touched. Any idea's how to solve this? Or any idea about what would be going wrong ? If it works when you run it directly, yet fails in the continuous build, then something is different between the two that matters. I would suggest running thetestin your continuous build environment with remote debugging enabled and attaching to it with a debugger to see what is going on. -- John A. Tamplin Software Engineer (GWT), Google -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
I give up for now :(... This issue is getting me against the roof... :( Even with remote debugging it all go well But let's not forget that the error only occurs sometimes: about 50% of the time and mostly during the day when I run the build manually when the server is more busy. During the night when the build server isn't doing much, most of the time the timeout exception doesn't occur. Almost always the exception occurs in a test class (extending GWTTestCase) that contains more then one test. As far as I can see, it never happens in test classes with only one test method... So it seems that more tests in one GWTTestCase class take more time and in someway triggers the timeout exception... Also, in case the timeout exception occurs, the logging indicates that the GWT servlet GWTShellServlet is correctly informed, but still the exception occurs... For now, I disabled these GWT test case that need the backend (through RPC) as I can't work with this unpredictable behavior. On Oct 5, 4:56 pm, Ed post2edb...@gmail.com wrote: running the test in your continuous build environment with remote debugging enabled and attaching to it with a debugger to see what is going on. Thanks again. John I did that already but will do it again now that I have a better understanding of the GWT Junit code. (I only have to use some tricks to attach the remote debugger correctly ...) On Oct 5, 4:24 pm, John Tamplin j...@google.com wrote: On Tue, Oct 5, 2010 at 10:12 AM, Ed post2edb...@gmail.com wrote: I found the servlet you meant: JUnitHostImpl I see that the url that touches this servlet is correctly forwarded by the proxy and received by this servlet when debugging in Eclipse: The url that touches it: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost (also appears in the logging below) However, when it's running during the nightly build and fails, I's hard to find out what went wrong as the this servlet doesn't contain debug/trace logging. It would be nice to see the path of execution in the logging such that I can see why the servlet isn't touched. Any idea's how to solve this? Or any idea about what would be going wrong ? If it works when you run it directly, yet fails in the continuous build, then something is different between the two that matters. I would suggest running the test in your continuous build environment with remote debugging enabled and attaching to it with a debugger to see what is going on. -- John A. Tamplin Software Engineer (GWT), Google -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
Yesterday my test was run with success and last night it failed again, without anything changing in the meantime :( I was digging a bit more in the GWT Junit test code and I think the test fails because I don't use a servlet that is hosted by the Tomcat container started by GWT. Like Freeland mentions above, I have to contact the backend within 60 sec to overcome the timeout exception. I think I have to contact a servlet run in the GWT Tomcat instance as otherwise it's not seen as a backend contact. Is this the true ? In my case, because I run in noserver mode, I run my own tomcat standalone server and use a proxy servlet that extends from GWTShellServlet to forward any business/servlet calls to my standalone server. So I never use any servlet in the GWT tomcat instance and as such receive a timeout exception when my tests don't run fast enough, which is what sometimes happens Please feedback on this and how I can solve this ? The only option I see now is: disable my GWT test cases as the current sometimes-failures is unacceptable on the build machine :( I have no idea how to solve it otherwise... On Oct 3, 8:10 pm, Ed post2edb...@gmail.com wrote: Just played with the -runStyle Manual option I am afraid that is not a correct option for me as I will run the tests during the nightly build and with -runStyle option Manual will stop when running the test and I have to manually copy/past the displayed url, like explained in:http://code.google.com/webtoolkit/doc/latest/DevGuideTesting.html#Man Of course this isn't possible during a nightly build. I will try the option -prod, this might bypass the HtmlUnit code that might give problems as you explain above. I tried this option in Eclipse and the test do run fine with this option. I hope this will solve the problem, as I have no idea what else it could be :( In Eclipse, the GWT tests always run fine (through launch files, I don't use the plugin), and never give me the timeout problem. If you have any more ideas, giving my posts above, please let me know? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
Hi John, Thanks for your reply. There are really two apps running in this case. First, there is the one created by JUnitShell, which contacts an RPC servlet to manage running the test. The timeout you see is because that servlet didn't get contacted. Could you please give me some more info and pointers here? I find the GWT Junit code difficult to follow, especially debugging is a bit hard. Where and how does this required servlet get contacted to overcome the timeout? If I follow the service method in GWTShellServlet, I don't understand where the required contact is made. And I can't find the relation with the messageQueue in the method JUnitShell.notdone() that must contain the required info to overcome the timeout exception :( The GWT Tomcat instance that contains my proxy servlet and my standalone Tomcat instance, run on the same server (the Cargo maven plugin starts the stanalone tomcat instance on port 8090) When you say noserver mode, what exactly do you mean? JUnitShell doesn't Maybe it's better not to use the word noserver in this case it might be misleading. I use the noserver mode during development mode with own launch files. In this case it doesn't make sense as GWT Junit always uses his own Tomcat instance like you explain. If you need a real browser to run the test in an automated way, the recommendation would be to use -runStyle Selenium:uri and run a Selenium-RC I also use Selenium, have about 2500 tests that run through Selenium, that take about 50 hours to complete ;)... Some background info: I don't use runstyle for this. I run the tests against production ready code produced during the nigtly build. I run my tests through testNG with Maven surefire plugin. I have build a little testing framework around Selenium RC in which case Selenium RC is just an implementation detail. I could also use other Ajax testing framework by creating a class that implements my Browser interface and connects to the testing framework. I model all elements on the screen that I want to test as objects and inject a Browser instance (link to Selenium). I then ask the element object something like isPresent(), isPresentWait(), typeText(String), etc... or in case of a DatePickerElement, something like: setDate(Date). The Date picker implementation will then open the date picker and choose the specified date and close it again. So you end up having a class hierarchy of Elements like TextElement, DateElement, etc I use it now for about two years and it works well and the tester that uses it, which isn't a experienced developers, likes it and can make his test scenarios well in eclipse... On Oct 5, 2:07 pm, John Tamplin j...@google.com wrote: On Tue, Oct 5, 2010 at 5:50 AM, Ed post2edb...@gmail.com wrote: Yesterday my test was run with success and last night it failed again, without anything changing in the meantime :( I was digging a bit more in the GWT Junit test code and I think the test fails because I don't use a servlet that is hosted by the Tomcat container started by GWT. Like Freeland mentions above, I have to contact the backend within 60 sec to overcome the timeout exception. I think I have to contact a servlet run in the GWT Tomcat instance as otherwise it's not seen as a backend contact. Is this the true ? There are really two apps running in this case. First, there is the one created by JUnitShell, which contacts an RPC servlet to manage running the test. The timeout you see is because that servlet didn't get contacted. Second, there is your actual test code, which may contact your own servlets that you create. Due to SOP, these must be on the same server that the code was loaded from, but your proxy servlet can run there and redirect the request to another server since it isn't bound by that restriction. In my case, because I run in noserver mode, I run my own tomcat standalone server and use a proxy servlet that extends from GWTShellServlet to forward any business/servlet calls to my standalone server. So I never use any servlet in the GWT tomcat instance and as such receive a timeout exception when my tests don't run fast enough, which is what sometimes happens When you say noserver mode, what exactly do you mean? JUnitShell doesn't support -noserver, since as mentioned above it's own servlet has to run to operate the test infrastructure. Please feedback on this and how I can solve this ? The only option I see now is: disable my GWT test cases as the current sometimes-failures is unacceptable on the build machine :( I have no idea how to solve it otherwise... -runStyle Manual was the suggestion for how to debug what is going on. There you should be able to see what is going wrong. If you need a real browser to run the test in an automated way, the recommendation would be to use -runStyle Selenium:uri and run a Selenium-RC server with the browser you want to test with. If you are on Linux, you can
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
Thanks, I found the servlet you meant: JUnitHostImpl I see that the url that touches this servlet is correctly forwarded by the proxy and received by this servlet when debugging in Eclipse: The url that touches it: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost (also appears in the logging below) However, when it's running during the nightly build and fails, I's hard to find out what went wrong as the this servlet doesn't contain debug/trace logging. It would be nice to see the path of execution in the logging such that I can see why the servlet isn't touched. Any idea's how to solve this? Or any idea about what would be going wrong ? Below the proxy part code that is very straightforward and some logging that might be of interest. In the logging I noticed that just after receiving the /junit url that should touch the JUnitHostImpl, a retry is attempted. Does that give you any ideas? protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { final String uri = createUriRequest(request); LOG.debug(Receiving url request, url: {}, uri); if (uriContainsRequestParts(uri)) { LOG.debug(Forwarding url to external system.\nUrl: {}\nTarget host: {}\nTarget port: {}\nTarget protocol: {}, new Object[] { uri, this.host, this.port, this.protocol }); proxy(request, response, uri); } else { LOG.debug(No forward. Calling parent method. Url: {}, uri); super.service(request, response); } } - The output snippet looks like: [INFO] 14:27:07.709 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - Receiving url request, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost [INFO] 14:27:07.709 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - No forward. Calling parent method. Url: /com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost [INFO] 14:27:10.891 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - Receiving url request, url: /bv- web/intern/rpc-gwt/srv-general [INFO] 14:27:10.892 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - Forwarding url to external system. ... ... [INFO] 14:27:12.909 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - Receiving url request, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost [INFO] 14:27:12.909 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - No forward. Calling parent method. Url: /com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost [INFO] [WARN] com.bv.gwt.profile.intern.ProfileGwtTest.JUnit:com.bv.gwt.profile.XGwtBackendTestUpdateLoggedInMemberOk.testUpdateLoggedInTaxer is being retried, retry attempt = 1 [INFO] [WARN] com.bv.gwt.profile.intern.ProfileGwtTest.JUnit:com.bv.gwt.profile.XGwtBackendTestUpdateLoggedInMemberOk.testUpdateLoggedInTaxer is being retried, retry attempt = 2 [INFO] Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 385.986 sec FAILURE! [INFO] testUpdateLoggedInTaxer(com.bv.gwt.profile.XGwtBackendTestUpdateLoggedInMemberOk) Time elapsed: 385.952 sec ERROR! [INFO] com.google.gwt.junit.client.TimeoutException: The browser did not contact the server within 6ms. [INFO] - NO RESPONSE: 192.168.1.45 / Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 [INFO] - 1 client(s) haven't responded back to JUnitShell since the start of the test. --- On Oct 5, 2:51 pm, John Tamplin j...@google.com wrote: On Tue, Oct 5, 2010 at 8:47 AM, Ed post2edb...@gmail.com wrote: There are really two apps running in this case. First, there is the one created by JUnitShell, which contacts an RPC servlet to manage running the test. The timeout you see is because that servlet didn't get contacted. Could you please give me some more info and pointers here? I find the GWT Junit code difficult to follow, especially debugging is a bit hard. Where and how does this required servlet get contacted to overcome the timeout? If I follow the service method in GWTShellServlet, I don't understand where the required contact is made. And I can't find the relation with the messageQueue in the method JUnitShell.notdone() that must contain the required info to overcome the timeout exception :( Look at the comment at the top of JUnitShell -- it explains the connections. If you need a real browser to run the test in an automated way, the recommendation would be to use -runStyle Selenium:uri and run a Selenium-RC I also use Selenium, have about 2500 tests that run through Selenium, that take about 50 hours to complete ;)... Some background info: I don't use runstyle for this. I run the tests against production ready code produced during
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
running the test in your continuous build environment with remote debugging enabled and attaching to it with a debugger to see what is going on. Thanks again. John I did that already but will do it again now that I have a better understanding of the GWT Junit code. (I only have to use some tricks to attach the remote debugger correctly ...) On Oct 5, 4:24 pm, John Tamplin j...@google.com wrote: On Tue, Oct 5, 2010 at 10:12 AM, Ed post2edb...@gmail.com wrote: I found the servlet you meant: JUnitHostImpl I see that the url that touches this servlet is correctly forwarded by the proxy and received by this servlet when debugging in Eclipse: The url that touches it: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost (also appears in the logging below) However, when it's running during the nightly build and fails, I's hard to find out what went wrong as the this servlet doesn't contain debug/trace logging. It would be nice to see the path of execution in the logging such that I can see why the servlet isn't touched. Any idea's how to solve this? Or any idea about what would be going wrong ? If it works when you run it directly, yet fails in the continuous build, then something is different between the two that matters. I would suggest running the test in your continuous build environment with remote debugging enabled and attaching to it with a debugger to see what is going on. -- John A. Tamplin Software Engineer (GWT), Google -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
Today the nightly build failed again and no compiler error occurred as appears in the above log snippet :( Below the concerning logging snippet. In the logging you see that the Proxy servlet does forward calls to the parent class: GWT servlet: GWTShellServlet (No Proxy forward in the logging means that it's not forwarded to the external tomcat server. So I don't understand the timeout error indicating that the no connection is made :(... I will now try the Runstyle option manual as you describe above. -- [INFO] 15:31:29.140 [main] INFO org.apache.catalina.startup.Embedded - Starting tomcat server [INFO] 15:31:29.243 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet Engine: Apache Tomcat/5.0.28 [INFO] 15:31:29.264 [main] INFO o.apache.catalina.core.StandardHost - XML validation disabled [INFO] 15:31:29.282 [main] INFO o.apache.catalina.core.StandardHost - Create Host deployer for direct deployment ( non-jmx ) [INFO] 15:31:29.288 [main] INFO o.a.c.core.StandardHostDeployer - Installing web application at context path from URL file:/ root/.hudson/jobs/Belastingvriendin/workspace/Belastingvriendin/bv-web- test/tomcat/webapps/ROOT [INFO] 15:31:29.614 [main] INFO o.a.coyote.http11.Http11Protocol - Initializing Coyote HTTP/1.1 on http-0 [INFO] 15:31:29.666 [main] INFO o.a.coyote.http11.Http11Protocol - Starting Coyote HTTP/1.1 on http-0 [INFO] 15:31:44.821 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - Receiving url request, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junit.html? gwt.codesvr=82.94.165.225:58507 [INFO] 15:31:44.846 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - No Proxy forward, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junit.html? gwt.codesvr=82.94.165.225:58507 [INFO] 15:31:45.625 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - Receiving url request, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/ com.bv.gwt.profile.intern.ProfileGwtTest.JUnit.nocache.js [INFO] 15:31:45.625 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - No Proxy forward, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/ com.bv.gwt.profile.intern.ProfileGwtTest.JUnit.nocache.js [INFO] 15:31:45.867 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - Receiving url request, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/hosted.html? com_bv_gwt_profile_intern_ProfileGwtTest_JUnit [INFO] 15:31:45.867 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - No Proxy forward, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/hosted.html? com_bv_gwt_profile_intern_ProfileGwtTest_JUnit [INFO] 15:31:47.897 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - Receiving url request, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost [INFO] 15:31:47.897 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - No Proxy forward, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost [INFO] 15:31:51.137 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - Receiving url request, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost [INFO] 15:31:51.137 [http-0-Processor4] DEBUG com.ited.gwt.dev.server.ProxyServlet - No Proxy forward, url: / com.bv.gwt.profile.intern.ProfileGwtTest.JUnit/junithost [INFO] [WARN] com.bv.gwt.profile.intern.ProfileGwtTest.JUnit:com.bv.gwt.profile.GwtBackendSubscribeMemberOkTest.testSubscribe is being retried, retry attempt = 1 [INFO] [WARN] com.bv.gwt.profile.intern.ProfileGwtTest.JUnit:com.bv.gwt.profile.GwtBackendSubscribeMemberOkTest.testSubscribe is being retried, retry attempt = 2 [INFO] Tests run: 8, Failures: 0, Errors: 8, Skipped: 0, Time elapsed: 382.879 sec FAILURE! [INFO] testSubscribe(com.bv.gwt.profile.GwtBackendSubscribeMemberOkTest) Time elapsed: 382.845 sec ERROR! [INFO] com.google.gwt.junit.client.TimeoutException: The browser did not contact the server within 6ms. [INFO] - NO RESPONSE: 82.94.165.225 / Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 [INFO] - 1 client(s) haven't responded back to JUnitShell since the start of the test. [INFO] Actual time elapsed: 60.015 seconds. [INFO] at com.google.gwt.junit.JUnitShell.notDone(JUnitShell.java: 896) [INFO] at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java: 1176) [INFO] at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java: 1198) [INFO] at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java: 1198) -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
Just played with the -runStyle Manual option I am afraid that is not a correct option for me as I will run the tests during the nightly build and with -runStyle option Manual will stop when running the test and I have to manually copy/past the displayed url, like explained in: http://code.google.com/webtoolkit/doc/latest/DevGuideTesting.html#Manual_Mode. Of course this isn't possible during a nightly build. I will try the option -prod, this might bypass the HtmlUnit code that might give problems as you explain above. I tried this option in Eclipse and the test do run fine with this option. I hope this will solve the problem, as I have no idea what else it could be :( In Eclipse, the GWT tests always run fine (through launch files, I don't use the plugin), and never give me the timeout problem. If you have any more ideas, giving my posts above, please let me know? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
(com.bv.gwt.declare.GwtBackendUpdateCategoriesOkTest) [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0 [INFO] [INFO] [ERROR] BUILD ERROR [INFO] [INFO] There was test failures. On Oct 1, 7:35 pm, Freeland Abbott fabb...@google.com wrote: On Fri, Oct 1, 2010 at 12:32 PM, Ed post2edb...@gmail.com wrote: Thanks for the detailed explanation, that sure helps. I have seen the timeout message happen due to a compile error in the GWT code, but you'd see those errors in the log also. Could it have something to do with issue 4700 ?: http://code.google.com/p/google-web-toolkit/issues/detail?id=4700 Nominally unrelated... 4700 is about benign-but-scary error messages resulting from sloppy gwt.xml specifications (and/or sloppy code arrangement) interacting with GWT's need to sniff around for all available classes rather than loading things only as referenced from your entry point. *However*, those benign-but-scary ones look just like less benign messages for actually referenced code, and *that* would be a fatal compilation error that, if I remember right, may indeed result in this timeout. Precisely, again if I remember, the client connects to the web server, gets a synthetic module that starts by making a GWT RPC to get the first test(s) to be run, and that RPC is what GWT didn't get in the one-minute timeout. If your code didn't compile, that RPC can't happen, and we time out. Failure to find source for classes we touch is one way to fail to compile (but identical-seeming errors for classes we don't touch are 4700). + I run the tests in noserver mode against an external tomcat server that runs the backend that is started by the cargo maven plugin. I use a proxy servlet in the internal tomcat server that is started by GWT like explained in issue 4615: http://code.google.com/p/google-web-toolkit/issues/detail?id=4615 Ah. I haven't attempted that pattern. More thoughts below, though. What is the relation between HTMLUnit and the internal tomcat that GWT uses ?.. None whatsoever: tomcat is a web server and servlet container; htmlunit is a web browser and JavaScript engine that happens to be (a) implemented in Java and (b) bundled into GWT. It sounds as though the RPC request for the junitshell servlet (i.e. JUnitHostImpl, implementing JUnitHost/JUnitHostAsync as an RPC interface) is not getting to our servlet; I can't tell you why. It might be misconfiguration in your proxy, and being sent to your tomcat server, which either wouldn't handle it or would handle it but not be the test infrastructure waiting for the call, and so the timeout would happen. Something like Charles or wireshark, or just close-reading your logs and configurations, might help you work out what was happening there. I suppose it might be that HtmlUnit is tripping itself up on startup, too, and sometimes not even making that RPC... same tools to diagnose. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Test timeout in JUnitShell ? (GWT 2.0.0)
Sometimes my GWT test's fail (during nightly build) and give me the following error. - [INFO] com.google.gwt.junit.client.TimeoutException: The browser did not contact the server within 6ms. [INFO] - NO RESPONSE: 192.168.1.65 / Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 [INFO] - 1 client(s) haven't responded back to JUnitShell since the start of the test. [INFO] Actual time elapsed: 60.004 seconds. -- This occurs when running my tests through the maven codehaus plugin, starting first tomcat with the cargo plugin. I played with the timeout settings I have in the maven and cargo plugin, but don't seem to be able to solve it. The maven plugin will run GWT test suites that extend from GWTTestSuite that contain test cases that extend GWTTestCase. The first GWT test suite always run with success and then the following GWT test suite gives the above error The code in JUnitShell throwing the above error: } else if (testBeginTimeout currentTimeMillis) { double elapsed = (currentTimeMillis - testBeginTime) / 1000.0; throw new TimeoutException( The browser did not contact the server within + TEST_BEGIN_TIMEOUT_MILLIS + ms.\n + messageQueue.getUnretrievedClients(currentTestInfo) + \n Actual time elapsed: + elapsed + seconds.\n); } I don't understand well how the testing with server/client concept works. Why is this timeout generated and how can I solve this? Shouldn't the timeout be adjustable as I the timeout is contained in the constant TEST_BEGIN_TIMEOUT_MILLIS ? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Test timeout in JUnitShell ? (GWT 2.0.0)
Thanks for the detailed explanation, that sure helps. I have seen the timeout message happen due to a compile error in the GWT code, but you'd see those errors in the log also. Could it have something to do with issue 4700 ?: http://code.google.com/p/google-web-toolkit/issues/detail?id=4700 Some more details: + I run the the tests with the following jvm arguments: -Xms756m -Xmx756m -Dcatalina.base.create=${project.basedir} - Dgwt.args=-logLevel INFO -Xtries 1 + I run the tests in noserver mode against an external tomcat server that runs the backend that is started by the cargo maven plugin. I use a proxy servlet in the internal tomcat server that is started by GWT like explained in issue 4615: http://code.google.com/p/google-web-toolkit/issues/detail?id=4615 What is the relation between HTMLUnit and the internal tomcat that GWT uses ?.. On Oct 1, 4:08 pm, Freeland Abbott fabb...@google.com wrote: That timeout means that GWT has launched a browser pointed at itself, to run the test, but the browser didn't actually connect to us within 60 seconds. The constant isn't directly configurable, no, but it's not about the size of your test, just getting that first useful access from the browser (so it's supposed to encompass browser start time + network latency; 60s should be way over adequate!). I have seen the timeout message happen due to a compile error in the GWT code, but you'd see those errors in the log also. I don't know much about the maven codehaus plugin, but here's roughly what GWT tests do: 1. GWT sets itself up as a web server on some random port. JUnitShell derives off the older GWTShell, so this should mean using our internal tomcat as the server. (I'm not sure your tomcat with the cargo plugin is relevant!) 2. That server is set to serve a synthetic GWT module, which is created via a generator that can reflect on your test code. 3. Depending on the -runStyle flag, GWT chooses a browser to launch. By default, we'd use HtmlUnit (mostly because we know where it is!), but there are other options available, including Manual (which has no timeout, and expects you to point a browser at GWT's server) and External (you give GWT an executable that accepts a URL as an argument). 4. If the browser we launch doesn't successfully access the web server we have, on that random port, you will get the timeout you cite. If it does access in time, the page should pull your code and start walking through the tests, reporting status and moving to the next test (or batch, depending on your batch strategy). I hope that helps. HtmlUnit does have some known issues, so especially if you see this happening sometimes you might want to experiment with either -runStyle Manual or -runStyle External to see if those are better-behaved for you. On Fri, Oct 1, 2010 at 9:06 AM, Ed post2edb...@gmail.com wrote: Sometimes my GWT test's fail (during nightly build) and give me the following error. - [INFO] com.google.gwt.junit.client.TimeoutException: The browser did not contact the server within 6ms. [INFO] - NO RESPONSE: 192.168.1.65 / Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 [INFO] - 1 client(s) haven't responded back to JUnitShell since the start of the test. [INFO] Actual time elapsed: 60.004 seconds. -- This occurs when running my tests through the maven codehaus plugin, starting first tomcat with the cargo plugin. I played with the timeout settings I have in the maven and cargo plugin, but don't seem to be able to solve it. The maven plugin will run GWT test suites that extend from GWTTestSuite that contain test cases that extend GWTTestCase. The first GWT test suite always run with success and then the following GWT test suite gives the above error The code in JUnitShell throwing the above error: } else if (testBeginTimeout currentTimeMillis) { double elapsed = (currentTimeMillis - testBeginTime) / 1000.0; throw new TimeoutException( The browser did not contact the server within + TEST_BEGIN_TIMEOUT_MILLIS + ms.\n + messageQueue.getUnretrievedClients(currentTestInfo) + \n Actual time elapsed: + elapsed + seconds.\n); } I don't understand well how the testing with server/client concept works. Why is this timeout generated and how can I solve this? Shouldn't the timeout be adjustable as I the timeout is contained in the constant TEST_BEGIN_TIMEOUT_MILLIS ? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Composite is evil?
I just uploaded the latest version of SimpleComposite in the issue: http://code.google.com/p/google-web-toolkit/issues/detail?id=2508 On Sep 14, 9:47 am, dflorey daniel.flo...@gmail.com wrote: I remember there once has been a LazyPanel in the incubator especially for use within TabPanels. Can you by chance provide your SimpleComposite src? Thanks, Daniel On Sep 12, 5:04 pm, Ed post2edb...@gmail.com wrote: I've never used lazy-loading within my composites and never felt the need for it; Lucky bastard ;) Of course you should always create your widgets as late/lazily as possible, but still.. it's not always that clear in complex app's with many nested widgets. As such, by embedding this behavior by default, you overcome this always, also for the times you forget it, or you don't even know about it. And it's a small change in the current Composite and a better programming style (= not creating it all in the constructor). I think you win a lot with little change. I use it now for a few years in production and have good experience with it. And there is one important point I forgot in the above list that I like to add: 3) The Composite class is hard to reuse in subclasses. It's inherent to point 1). That's what gave my headaches when I start to use it years ago.. ... : ( Example: Suppose you have a Composite that shows a textbox. No suppose you want to subclass this to add a checkbox in front of the textbox. This is hard (because it's all created in the constructor), possible but ugly. Of course it's possible by creating the correct protected methods that create the text box that you can then override. But don't forget that this method is called from within the constructor such that it becomes ugly. It's not for nothing that tools like PMD and Checkstyle complain when you call a not-private method (or not final protected/public method) within your constructor. On Sep 12, 4:00 pm, Thomas Broyer t.bro...@gmail.com wrote: On Sep 12, 1:57 pm, Ed post2edb...@gmail.com wrote: I long time ago I opened an issue about the Composite widget:http://code.google.com/p/google-web-toolkit/issues/detail?id=2508 I think the Composite widget should be improved because: 1) Creating all widgets in the constructor is an anti-pattern (evil) like discussed in for example the book effective programming. 2) It's not lazy loading any widget. To not get any problems using the Composite widget you should use call the initWidget() method in the constructor, meaning that you have to create your widget in the constructor Something like this: public MyWidget() { initWidget(createMyWidget()); } In case the method createMyWidget() call several other Composite widgets, this can be slow operation without that you realize it as you don't really know that the called composite widgets do. I think you only want to create all these widgets when it's needed (the lazy loading idea). I remember that GWT Designer of Instantiations is also creating all the widgets directly in the constructor (at least it was about a year ago).. I often see this at clients that use gwt designer, that all widgets are created too early instead of lazily which has an performance impact. More advanced gwt developers probably recognize this and have a simple answer: use the onAttach/onCreated method to create all your widgets and simple call initWidget in the constructor with only the outer panel, which can be a simple div... I started like this as well, and then end up creating my own SimpleComposite that extends Composite and only asks the subclasses to create the widget when it's needed, as such getting real lazy creation of the widgets, which I think should be an important goal. However the gwt beginners, will not start like that and will create their widgets to early and all in the constructor. Why not make this kind of lazy-behavior more standard in the current Composite implementation such that all gwt developers are using it without even knowing it and no need to think extra about it? I like to hear your feedback about this and maybe the gwt dev team can have a look at it (maybe after 2.1 is out). Well, if you instantiate a composite to only attach it later, then maybe you should just instantiate the composite a a later time? I mean, I understand what you're saying, but I think in many cases it's actually a non-issue. I've never used lazy-loading within my composites and never felt the need for it; I instead lazy-load the composite itself (using Gin Providers or other factory pattern). -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Composite is evil?
Having lazy behavior in this LazyPanel, why not put it in other widgets like the Composite ;) On Sep 14, 11:32 am, Thomas Broyer t.bro...@gmail.com wrote: On Sep 14, 9:47 am, dflorey daniel.flo...@gmail.com wrote: I remember there once has been a LazyPanel in the incubator especially for use within TabPanels. The one that graduated into GWT proper? ;-)http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/g... -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Composite is evil?
Thanks John, I am familiar with the lazy loading and code splitting and use it a lot as it's an important issue in my gwt app's. That's one of the reasons that SimpleComposite came to existence. Many API methods depend on the widget being initialized. We would have to cache a lot of values prior to initialization, or we'd have to have a really This is a bit black-white scenario. There is an intermediate way between caching all, like happens in SimpleComposite. Simple cache the main things that are needed at the start, and if other things are needed, simple ask the subclass to create the rest Code Splitting should be more used on macro level and the lazy loading as happens in LazyPanel and SimpleComposite on a micro level. This keeps things clear and easy to understand. On Sep 14, 4:52 pm, John LaBanca jlaba...@google.com wrote: Having lazy behavior in this LazyPanel, why not put it in other widgets like the Composite ;) Many API methods depend on the widget being initialized. We would have to cache a lot of values prior to initialization, or we'd have to have a really aggressive initialization policy, which could make debugging very difficult. If you don't expect a part of your app to be used immediately, you should initialize it lazily. You should also look at code splitting to break down the size of your downloaded app:http://code.google.com/webtoolkit/doc/latest/DevGuideCodeSplitting.html Thanks, John LaBanca jlaba...@google.com On Tue, Sep 14, 2010 at 7:51 AM, Ed post2edb...@gmail.com wrote: Having lazy behavior in this LazyPanel, why not put it in other widgets like the Composite ;) On Sep 14, 11:32 am, Thomas Broyer t.bro...@gmail.com wrote: On Sep 14, 9:47 am, dflorey daniel.flo...@gmail.com wrote: I remember there once has been a LazyPanel in the incubator especially for use within TabPanels. The one that graduated into GWT proper? ;-) http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/g... -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Composite is evil?
I long time ago I opened an issue about the Composite widget: http://code.google.com/p/google-web-toolkit/issues/detail?id=2508 I think the Composite widget should be improved because: 1) Creating all widgets in the constructor is an anti-pattern (evil) like discussed in for example the book effective programming. 2) It's not lazy loading any widget. To not get any problems using the Composite widget you should use call the initWidget() method in the constructor, meaning that you have to create your widget in the constructor Something like this: public MyWidget() { initWidget(createMyWidget()); } In case the method createMyWidget() call several other Composite widgets, this can be slow operation without that you realize it as you don't really know that the called composite widgets do. I think you only want to create all these widgets when it's needed (the lazy loading idea). I remember that GWT Designer of Instantiations is also creating all the widgets directly in the constructor (at least it was about a year ago).. I often see this at clients that use gwt designer, that all widgets are created too early instead of lazily which has an performance impact. More advanced gwt developers probably recognize this and have a simple answer: use the onAttach/onCreated method to create all your widgets and simple call initWidget in the constructor with only the outer panel, which can be a simple div... I started like this as well, and then end up creating my own SimpleComposite that extends Composite and only asks the subclasses to create the widget when it's needed, as such getting real lazy creation of the widgets, which I think should be an important goal. However the gwt beginners, will not start like that and will create their widgets to early and all in the constructor. Why not make this kind of lazy-behavior more standard in the current Composite implementation such that all gwt developers are using it without even knowing it and no need to think extra about it? I like to hear your feedback about this and maybe the gwt dev team can have a look at it (maybe after 2.1 is out). Thanks, Ed -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Composite is evil?
I've never used lazy-loading within my composites and never felt the need for it; Lucky bastard ;) Of course you should always create your widgets as late/lazily as possible, but still.. it's not always that clear in complex app's with many nested widgets. As such, by embedding this behavior by default, you overcome this always, also for the times you forget it, or you don't even know about it. And it's a small change in the current Composite and a better programming style (= not creating it all in the constructor). I think you win a lot with little change. I use it now for a few years in production and have good experience with it. And there is one important point I forgot in the above list that I like to add: 3) The Composite class is hard to reuse in subclasses. It's inherent to point 1). That's what gave my headaches when I start to use it years ago.. ... : ( Example: Suppose you have a Composite that shows a textbox. No suppose you want to subclass this to add a checkbox in front of the textbox. This is hard (because it's all created in the constructor), possible but ugly. Of course it's possible by creating the correct protected methods that create the text box that you can then override. But don't forget that this method is called from within the constructor such that it becomes ugly. It's not for nothing that tools like PMD and Checkstyle complain when you call a not-private method (or not final protected/public method) within your constructor. On Sep 12, 4:00 pm, Thomas Broyer t.bro...@gmail.com wrote: On Sep 12, 1:57 pm, Ed post2edb...@gmail.com wrote: I long time ago I opened an issue about the Composite widget:http://code.google.com/p/google-web-toolkit/issues/detail?id=2508 I think the Composite widget should be improved because: 1) Creating all widgets in the constructor is an anti-pattern (evil) like discussed in for example the book effective programming. 2) It's not lazy loading any widget. To not get any problems using the Composite widget you should use call the initWidget() method in the constructor, meaning that you have to create your widget in the constructor Something like this: public MyWidget() { initWidget(createMyWidget()); } In case the method createMyWidget() call several other Composite widgets, this can be slow operation without that you realize it as you don't really know that the called composite widgets do. I think you only want to create all these widgets when it's needed (the lazy loading idea). I remember that GWT Designer of Instantiations is also creating all the widgets directly in the constructor (at least it was about a year ago).. I often see this at clients that use gwt designer, that all widgets are created too early instead of lazily which has an performance impact. More advanced gwt developers probably recognize this and have a simple answer: use the onAttach/onCreated method to create all your widgets and simple call initWidget in the constructor with only the outer panel, which can be a simple div... I started like this as well, and then end up creating my own SimpleComposite that extends Composite and only asks the subclasses to create the widget when it's needed, as such getting real lazy creation of the widgets, which I think should be an important goal. However the gwt beginners, will not start like that and will create their widgets to early and all in the constructor. Why not make this kind of lazy-behavior more standard in the current Composite implementation such that all gwt developers are using it without even knowing it and no need to think extra about it? I like to hear your feedback about this and maybe the gwt dev team can have a look at it (maybe after 2.1 is out). Well, if you instantiate a composite to only attach it later, then maybe you should just instantiate the composite a a later time? I mean, I understand what you're saying, but I think in many cases it's actually a non-issue. I've never used lazy-loading within my composites and never felt the need for it; I instead lazy-load the composite itself (using Gin Providers or other factory pattern). -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: RPC policy files usage?
) { this.allowHasPreferenceOverNotAllow = yes; } public boolean contains(final Class? item) { Args.notNull(item); return UtilsMiscSafe.isAllowedString(item.getName(), allowed, notAllowed, allowHasPreferenceOverNotAllow); } } - And the method isAllowedString: /** * In case both the allowed and not allowed collections are empty or null, all item's are allowed.br * This version is almost the same as {...@link #isAllowed(Object, Collection, Collection, boolean)}, but it can only be used with String * as input and can deal with * at the end of a string to match only the beginning of the string.br * Example: suppose allowed contains com.ited.* and the item has value com.ited.bla.bla. The item will be matched as an item contained * in the allowed items. The same counts for the not allowed collection. * * @return true if allowed, false otherwise. */ public static boolean isAllowedString(final String item, final CollectionString allowed, final CollectionString notAllowed, final boolean allowHasPreferenceOverNotAllow) { Args.notNull(item); if (isEmpty(allowed) isEmpty(notAllowed)) { // all allowed return true; } else { if (hasContent(allowed)) { final boolean isAllowed = contains(item, allowed); if (isAllowed !allowHasPreferenceOverNotAllow hasContent(notAllowed)) { // not allowed has preference return !contains(item, notAllowed); } else { // not allowed is not of interest return isAllowed; } } else { // only not allowed has content return !contains(item, notAllowed); } } } /** * @return true if the value is contained in the collection, allowing only the first part to match if the collection item ends with *. */ private static boolean contains(String value, CollectionString col) { for (String item : col) { if (item.endsWith(*)) { if (value.startsWith(item.substring(0, item.length() - 1))) { // found a match return true; } } else { if (item.equals(value)) { // found a match return true; } } } return false; } I inject it through Spring, so my spring config will look something like this: - !-- The GWT policy = -- bean id=gwtPolicy class=com.ited.gwt.server.SerializationPolicySimple constructor-arg index=0 ref=gwtPolicyAllowed / constructor-arg index=1 ref=gwtPolicyAllowed / /bean !-- The objects that are allowed to be serialized/deserialized by GWT = -- bean id=gwtPolicyAllowed class=com.ited.lang.misc.ContainsAllowedString constructor-arg index=0 list valuecom.ited.*/value valuecom.bv.*/value valuejava.lang.*/value value[Ljava.lang.String;/value valuejava.util.*/value valuejava.sql.*/value /list /constructor-arg constructor-arg index=1 list valuejava.lang.Object/value /list /constructor-arg /bean -- I might have to optimize bits and pieces in the future but it's good for now... Ed -- 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: RPC policy files usage?
Hi, I am a bit lost here. I mean, I don't really understand why I even need these policy files and why they aren't more flexible in usage (maybe even optional). If I am correct, it's there for security reasons, it's used to indicate which objects are allowed to be (de)serialized. But what if I don't want that, or if I want to do it in another way? If I look at my gwt app's, security is well taken care of, so I don't think I need these policy files. However, at this moment it's very hard to not-use them :( and it cost developers (a lot of time) to use them in a more complex enterprise-like environment. Ed -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: RPC policy files usage?
I gave the above remote context some more thoughts, and it's not an option: - I run in the following environments: dev, test, acceptance, production and build. The dev and build environments are the ones that give me problems as I run GWTTestCase's in these mode's with a proxy servlet to forward the call to the running tomcat instance (-noserver mode) (server is started/stopped through the maven cargo plugin). The gwt tests run in gwt modules that aren't reachable through HTTP, so the above Remote context isn't an option. Sometimes my tests fail during dev or our nightly build because the polixy file is outdated and need to be replaced... This isn't a desired situation: the build being dependent on policy file not being up2date :( I hope to get some more details through the forum to implement my own SerializationPolicy. I think that is still my best workable option. At this moment, these policy files cost me a too much time, and I tried several options now through the years.. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: RPC policy files usage?
Thanks for your thoughts Alex. The solution is a bit like discussed above with Ladislav. I am still not so happy about retrieving this rpc files from different locations in different environments and also having to configure a HTTP context in the build/dev environment to be able to retrieve the policy files I still think this should be more simple for just dealing with a few policy files. I think my best option, to make handling the policy files easy, is to implement my own SerializationPolicy class. But, I have no idea if that is correct way to go as I can't find correct information about it :(. Any idea's on how to do this are more then welcome? Ed -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Re: RPC policy files usage?
He, to fetch them using HTTP connection to appropriate client. Indeed, that doesn't sound that bad, but I will need to maintan a mapping between the moduleBaseUrl that I receive in the backend and the actual http url of the module location where I can find the policy file. And these mappings are different in development and production mode. But, if you think about it, it will probably be the best option if you want to deal with policy files. The other little disadvantage would be the HTTP communication whereas the files are located on the same server. But, that doesn't take away the disadvantage of having all these duplicate entries in the policy files. What about implementing my own SerializationPolicy class and simple filter on, for example the package name, to indicate if an object is allowed to be serialized/deserialized.? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] RPC policy files usage?
I like to start a discussion on the usage of the RPC policy files in noserver mode, and I am interested if this might be improved. Let me explain my use case and show my problems that I experience. I have 4 GWT app's connecting all to the same backend app. All GWT app's have two backend interfaces to the backend, and they also have a dev and test app each. This will produce a total of 24 gwt.rpc files. Every time that gwt complaints during dev mode about not finding a gwt.rpc file I copy it manualy to the server such that it's packages in the war and restart the server. This is costy and takes a lot of time during development. At this moment I have about 50 gwt.rpc files in my backend as I don't know which one is old and it takes too long to find that out every time. The gwt.rpc files contain a lot of duplicates entries also. I think that I am doing something wrong as I don't think this is the correct way. I will start using the new DeRPC mechanism shortly and understand that the rpc files aren't needed anymore during dev mode, however because I am running in noserver mode I don't think this gives me any improvement. However, I still looking for a good way to use these files during testing/production. Please some advice on this? I think that I should collect all created gwt.rpc files (at least of the test and production app's) and include them in my war, or not?.. However, the problem I am having with this solution is that I am building all with maven and means that I need to make the web project dependent of the gwt app's, such that they are build first before the war is build. This dependency isn't welcome in my project, unclear and error phrone. Can others please share how they solved this? I then still many policy files that contain duplicated entries. I would be nice if these could be merged some how. But let's go back to the goal of the policy files like I understand it: Indicates which files are allowed to be serialized. At this moment this is done through creating policy files that contain the classes that are allowed to be serialized. Like explained above, this creates a undesired situation. This results in creating policy files that have to be pushed from the front-end to the backend. But what about calculating the policy in the backend and not create a dependency between the backend and front-end? For example: I could return my own implementation of the SerializationPolicy class that indicates which class can be serialized depending on the package name However, will this work and is this good enough? I think it is in my case as I use some other security mechanism to gaurantee a certain security level, but I can't find good information about the content of the policy files, so it's difficult for me to make the correct design decisions. Please some feedback? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Re: RPC policy files usage?
Hi Ladislav, Thanks for your response. I do almost the same thing as Acris does, I only have my files located in the classpath (I also use GWT-SL to read my policy files).. But Acris also doesn't solve the problem of having all these policy files scattered around and assumes that you have them somewhere available in a local or remote context. However, they don't explain how to get them there, which is exactly my problem and not very friendly to my experience (they also refer to using ant copy actions to collect them). -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: compiler placeholders - symbol map
Please some advice on the above? --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] compiler placeholders - symbol map
I like the idea of the symbol map in gwt 2.0 and would love to be able to use/extend it myself. I would like to get feedback on the following idea: I would like to put a placeholder in my gwt code that is replaced by a GWT unique ID and that is put in a symbol map. Wny? I like to use this in my exceptions such that I can trace back the location where I throw the exception which is send to the backend. With the data that is contained in the exception I can uniquely identify the problem. I did this now by creating the id manual; like using the class name with some postfix id, but the above solution would work better I think: simple, isolated and straightforward. Is something like this possible? or will it be possible? Can I add/ extend the compiler with my own decorator? --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Focus/blur on a group of widgets?
Thanks for the feedback Joel and John .. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Focus/blur on a group of widgets?
I asked around on the net and got the idea that it's not possible at all. I think because these events are received from the underlying OS and simple forwarded, which makes sense I think it would be possible if you use a kind of delayed-pipeline (pattern): holding on to an event till some condition is met before forwarding itExample of the condition: till a maximum delay time is reached and/or the focus of the previous blur event is received. The advantage would be to receive the blur and focus event together in one event as a kind of paired event. So you can immediately find out which widget (if there is any) receives focus on a blur event... --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Focus/blur on a group of widgets?
Hello Ray, If you have a minute, could you please answer my question above? I am very curious what you mean. Tanks On Aug 31, 4:33 pm, Ed post2edb...@hotmail.com wrote: Hello Ray, Thanks for your reply. Don't fake it, replace it: have your composite widget implement HasValueDate (or whatever). I am sorry, but I can't follow you here :(... What do you mean ? --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Focus/blur on a group of widgets?
Tanks Ray, I understand what you mean but don't really see how this could solve my problem. My problem is to detect a single focus/blur event of a group of widgets. Looking at your explanation I do translate these events to a general ValidationChange event. However, to trigger the validation of my composite widget I have to detect a single blur (like explained above of the examples). Reading your explanation; my problem is the implementation of this semantic event as the client won't see this blur/focus event directly, but the ValidationChangeEvent. Is there anyway to analyze the upcomming gwt events, when receiving a gwt event? In this way I can see if a focus event of one of the widgets in the group is following the blur event, so I can decide if the blur event is a blur of the whole group of widgets --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Focus/blur on a group of widgets?
Hi, I need to support a single focus/blur of a group of widgets. Please some advise on this? Examples: 1) Date (Birtyday) field that consists of 3 small text boxes, that can be filled in by the user. 2) Date picker field: two date pickers to select a period. It's important that 1) and 2) form one widget with a single focus/blur event. This is needed for further actions that depend on these events. For example: Form validation that occurs when a blur occurs. You don't want to do a blur validation when the user is still filling in the form and selects the other date field in 1) or the end date of the date picker in 2). The blur will do validation and shows the validation result. However, if the user is still busy filling in the widget, you don't want to show some alert box. Implementation: I solved this with a WidgetGroupFocus object that contains widgets and will control the focus/blur events. On a blur it will hold the blur event and run a DeferredCommand to see if a focus event occured on one of the containing widgets in the meantime. If yes, the blur event is ignored, other wise the blur is distributed to the subscribers. This has two major disadvantages: 1) The global blur event will always be informed after the focus event. As described above the blur event will be hold, to determine if a focus event occurred on a widget that is outside the widget group. In case this happens, the blur will be distributed after the focus event (normally it's the other way around). However, I can live with this... 2) The hold event can't be re-used. The hold blur event can't be distributed as the same event after it has been hold as it might give problems when the event is further processed, as GWT is already processing other events. So GWT will throw exceptions like the ones below when doing so (like expected). In the past with the older event model this wasn't such an issue as the listener didn't receive an event directly. com.google.gwt.core.client.JavaScriptException: (Error): Member not found. number: -2147352573 description: Member not found. at com.google.gwt.dom.client.DOMImpl.eventGetType(Native Method) --- Bottom line: the solution isn't so elegant so I am looking for a better way of solving this. This might not be so difficult if it's possible to be able to look on the event queue when receiving a blur event. If the queue contains the upcoming focus event that caused the blur event, the blur could be ignored (in my case) But I have no idea how to do this, or if this is possible. I played with the NativePreviewEvent to see if I could detect the upcoming focus event that follows the blur event, but that has no luck... Any idea's? --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Focus/blur on a group of widgets?
Hello Ray, Thanks for your reply. Don't fake it, replace it: have your composite widget implement HasValueDate (or whatever). I am sorry, but I can't follow you here :(... What do you mean ? --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: insertPanel interface
Hi Bruce, My first reaction to you email: laughing ... but on second thought I can't resist to react. People warned me for your, but I never expected this! I don't like the tone of your post just like you don't like mine. If you want to kick me out of the forum, or want to filter any of my emails, please, I invite you to do so (please also remove any of my issue tickets and forum post)! Do what you think is right. I you prefer putting your valueable time in filtering my emails/kicking me out, instead of trying to understand my examples/post, please do so! If you want me to adress you with Sire next time, please let me know, and I will do so if that makes you feel good. It very weak and incorrect to use this right to kick me out. I understand it's the easy way for you, but it's not the correct way to solve this. If you don't like my tone, why didn't you say it sooner instead of letting it come so far?.. and throwing this post at me, a bit childness don't you think... Especially as I don't really have something equal to throw at you... I am sorry for beeing direct, I will be more careful next time, but at least I got your attention now! This is not a one way street, you might also take the effort to understand where this is coming from and take a look at some history here. It's not the first time you just bounce in, make some vague remarks and take off... Just take our discussion about a year ago: I gave some examples, and you bounce in with this general remark: we don't change unless we get specific clear use cases. So I take the effort to gave them to you... And you don't even take the effort to reactjust all quiet... nobody home . Now I take the effort again to refresh my mind about this all HandlerManager, and you just make it dead... I understand it, but why did we start it in the first place if the priority isn't high enough... You wan't more? Now again you make me laugh if you tell me that I fail in giving correct examples... :)... Please take the effort to have a closer look or just don't react at all. .. If you really would have taken an effort to look at my examples/use cases, you would not make vague remarks like specific use cases or failing examples. No... instead you would ask detail questions about my examples, and indicate what you don't understand. Appearantly you are failing in doing this so far! What is it what you don't understand about the above example? I what way am I failing? Please explain to me so I can learn something! Let's also not forget that I refer to an issue that already contains a clear example of Fred, which comes down to the same thing as the example above. So how many more examples do you need? (just like with the widget interface discussion)... This is email not a face-2face conversation so I can't smell or see that my examples aren't clear enough, so please ask and I will do my best to make it more concrete! Talking about email: everybody over the whole world uses this forum, and you can't expect everybody to email the way you want, so try to understand the criticism the way I write it here behind my laptop in my country, instead of your world! Why do you even start an open forum if you can't accept and respect this different kind of criticism from all over the world? My advice: take a bit of a holiday and relax...:) Have a nice weekend. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: insertPanel interface
Hi Miroslav Thanks for the feedback. You make a good point there about the increase in the amount of javascript due to the interface.. I wasn't aware of that and would love to hear about this. It makes you wonder what is better. I mean: using these interfaces also safes code as I can re-use code that works agains different implementations, I think it's better progamming, overcomes code duplication and reduces bugs... But at the other end the amount of code increases... --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: insertPanel interface
He Joel, You are right about this. Like explained, I will be more careful next time, as I didn't realize it would be taken this way. Maybe it's the world/country I live in... I don't know... but it's not important.. Anyway, in this case, the patch was already in the issue not ? If you need more.. or a patch about another issue, let me know? --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Questions and concerns with HandlerManager
Even do it's dead, let me give some pointers on the Source generic issue that came in mind: - My Source isn't part of my HandlerManager, as in the example of Joe above. - My Source is contained in the event builder and his type indicated on the event builder through Generics. - The source can be passed in every time an event is fired if you wish. - I don't think that event delegation is any problem. If I understand you correctly, I certainly do this and have no problems with it. Here example code of usage (The Form Generic is the Source): this.formValidationListenerReg = input.addValidationChangeListener(new OnValueSourceListenerForm, Boolean() { public void onValue(final OnValueSourceEventForm, Boolean event) { handleFormValidationChange(event.getValue()); } }); I am now using it since about 6 months a lot (I work with GWT 24 hours the last few years) and it works very well... Have a nice weekend --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Questions and concerns with HandlerManager
It costs me a bit to go back in time as these issues are already from some time back.. Let me try to give some input on these points. 2) I don't fully understand what the problem is here. Could you give an example that shows that it breaks? Anyway, let me explain a bit how my handlermanager works as I don't seem to have this problem yet... but neither do I think it solves it (I did this somewhere on the forum already... I think but but can't find it 123) In my implementation I can specify the source through generics as I found it important due to experience in the past. It makes it more clear and tight about what to expect in the listener event (the element of least-suprise). The steps for firing an event are almost the same, except: - I bought myself some extra freedom by introducing an extra eventbuilder object that contains the event (kind of intermediate object). The event is a stupid value object without any extra logic like the GWT event. This is takes away the need for the gwt package protected event methods btw. I moved the logica that GWT put in the gwt event in my eventbuilder, such that they al have their simple and clear responsibility. I think the current gwt event contains/does too much. I experience this when trying to extend/use it, this is difficult/not possible... The event builder will call the listener and pass in the contained event. I use the builders as flyweight object and reuse them. The event builder is passed to the fireEvent(..) method of the HandlerManager. This is an interface of which if have several sub interfaces to add extra functionality like the interceptor construction. The HandlerManager will ask the event builder to fire the event passing in the register that holds all the listeners. The event builder will then ask the register to fire the event, passing in himself. The register will retrieve all interested listeners through the type that is contained in the event builder, and will then ask the event builder to dispatch the event to the listener, passing in the listener (one by one) I might sound a bit cumberslume.. al these forward calls (visitor pattern) (at least I think it is).. but I needed it to keep it tight and use my generics correctly... If you want a the dirty details I really have to dig in to it again... Anyway: the above construction I needed to win extra freedom to add extra functionality like the interceptor, stop delegation, etc.. and to work with different implementations againts common interfaces (which currently isn't possible with the GWT implementation as the gwt event contains too many things: logica and data. Ofcourse this is desired looking from a rich object perspective, but you don't want to expose all the delegation to the subscribers... I mean: they can stop the delegation, but that's about it... Maybe the above will give some idea's. 3) Ok, let me give an example and hope I have some luck here... ;) I remember we had this same discussion about primitive-simple Widget interfaces, you asked me the same thing (together with Bruce), I gave some concrete interfaces.. and never heard anyting :(... My app is very simple in layout: a menu on the left and the content on the right. You can navigate to another piece of content by clicking on the next/prev button in the content screen part or by clicking in the menu. If the user navigates away from the current content screen (by clicking next/previous... or the menu), and the current shown content isn't valid, he will be asked for a confirmation. If yes, the action (=going to the new content and saving the current shown content) will be performed, if no, the action is canceled and he stays on the same content screen. I implement this through an interceptor (aynchrone in this case) that will take care of the confirmation and some other side-actions. It makes it clean and transparent. What I do roughly: I inject the interceptor in the presenter. When the select value in the model changes it will first inform the interceptor with a callback. The call back contains different methods that are called by the HandlerManager implementation to indicate success/ cancelation. In case of success (the user clicks Ok), it will inform the callback about this such that the property change can be made permanent. The handlermanager will then inform the listeners and after that call the callback to indicate that they are all informed If you need more details, let me know ? After describing the above, you might understand that it's desirable to open up the GWT Handlermanager to add these functionality directly to it, instead of making a copy and changing it.. Probably this is need in my case anyway... but still... Hope this helps... --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Questions and concerns with HandlerManager
class HandlerManagerSource { ... } Interesting how you put Generics in the HandlerManager Of course this is a no go area as you explained. Try my HandlerManager scenario like I described above; only the event contains the actual source generics, and of course not he HandlerManager... Let me know if you want some code of this ? So I can grep something together... I might need a bit of time for that... and let me know where to send it to? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? H... I could give some code, but I think in words the need for the interceptor is clear: The user selects something and the interceptor will indicate if the selection is allowed to be committed (like a 2-phase db transaction) or not.. Can you give me more details about what you not understand here please? I am afraid that the code only make it less understandable as it's complex.. due to the asynchrone behavior. If you could describe *precisely* what you think should be opened up in HandlerManager, it would help me to make a reasonable judgment. As it stands, it all seems very vague to me. H... can't remember the *precise* details anymore... it was already some time ago... :( One thing I remember was that I wanted to change the source in the HandlerManager, which wasn't possible as it can only be set through the constructor.. On Aug 7, 10:07 pm, Joel Webber j...@google.com wrote: On Fri, Aug 7, 2009 at 1:34 PM, Ed post2edb...@hotmail.com wrote: It costs me a bit to go back in time as these issues are already from some time back.. Let me try to give some input on these points. 2) I don't fully understand what the problem is here. Could you give an example that shows that it breaks? It's actually worse than I thought. If I add a type parameter to HandlerManager, I get something like class HandlerManagerSource { ... } But I have no way to specify the source type when it's declared in Widget: class Widget { HandlerManager??? handlerManager; } The Source type parameter would force me to declare a separate HandlerManager field in each subclass of Widget. But then I can't subclass a widget and get the source type correct -- I'd need *another* handlerManager field. 3) Ok, let me give an example and hope I have some luck here... ;) I remember we had this same discussion about primitive-simple Widget interfaces, you asked me the same thing (together with Bruce), I gave some concrete interfaces.. and never heard anyting :(... My app is very simple in layout: a menu on the left and the content on the right. You can navigate to another piece of content by clicking on the next/prev button in the content screen part or by clicking in the menu. If the user navigates away from the current content screen (by clicking next/previous... or the menu), and the current shown content isn't valid, he will be asked for a confirmation. If yes, the action (=going to the new content and saving the current shown content) will be performed, if no, the action is canceled and he stays on the same content screen. I implement this through an interceptor (aynchrone in this case) that will take care of the confirmation and some other side-actions. It makes it clean and transparent. What I do roughly: I inject the interceptor in the presenter. When the select value in the model changes it will first inform the interceptor with a callback. The call back contains different methods that are called by the HandlerManager implementation to indicate success/ cancelation. In case of success (the user clicks Ok), it will inform the callback about this such that the property change can be made permanent. The handlermanager will then inform the listeners and after that call the callback to indicate that they are all informed If you need more details, let me know ? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? After describing the above, you might understand that it's desirable to open up the GWT Handlermanager to add these functionality directly to it, instead of making a copy and changing it.. Probably this is need in my case anyway... but still... If you could describe *precisely* what you think should be opened up in HandlerManager, it would help me to make a reasonable judgment. As it stands, it all seems very vague to me. Thanks, joel. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Questions and concerns with HandlerManager
Then I would declare it dead Bruce! With all do respect: I do very complex things with GWT and do walk on his boundaries... And to my experience - I am a bit lonely out here... (yes I know it sounds a bit arrogant...) And yes, I agree that you guys have better things to do to make GWT first more mature before they support these complex things... Buttt... it would be nice if these things aren't forgotten and put on the nice-to-have list... and not on the forget-list. I think that adding (more) primitive (characteristic) widget/panel interfaces, like we discussed before has an higher priority, so I hope you guys add this to gwt 2.0. I am still suprised about the few people complain about this. But I have pointed out concrete clear cases that show the need for this...(like you asked before) Just my thoughts... BTW: Joe if you want some code about my HandlerManager to be able to define the source through generics, let me know... On Aug 7, 10:55 pm, Bruce Johnson br...@google.com wrote: Are there lots of folks on the list that have the same sorts of feedback on HandlerManager? I ask because, as a fly on the wall here, this conversation doesn't sound like it's converging, and I'd like to declare this thread dead for now so that we can move onto other things. We have a lot of other things to be giving attention to so that we can get GWT 2.0 out. If we need to revisit these issues in the future, we certainly can. -- Bruce On Fri, Aug 7, 2009 at 4:43 PM, Ed post2edb...@hotmail.com wrote: class HandlerManagerSource { ... } Interesting how you put Generics in the HandlerManager Of course this is a no go area as you explained. Try my HandlerManager scenario like I described above; only the event contains the actual source generics, and of course not he HandlerManager... Let me know if you want some code of this ? So I can grep something together... I might need a bit of time for that... and let me know where to send it to? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? H... I could give some code, but I think in words the need for the interceptor is clear: The user selects something and the interceptor will indicate if the selection is allowed to be committed (like a 2-phase db transaction) or not.. Can you give me more details about what you not understand here please? I am afraid that the code only make it less understandable as it's complex.. due to the asynchrone behavior. If you could describe *precisely* what you think should be opened up in HandlerManager, it would help me to make a reasonable judgment. As it stands, it all seems very vague to me. H... can't remember the *precise* details anymore... it was already some time ago... :( One thing I remember was that I wanted to change the source in the HandlerManager, which wasn't possible as it can only be set through the constructor.. On Aug 7, 10:07 pm, Joel Webber j...@google.com wrote: On Fri, Aug 7, 2009 at 1:34 PM, Ed post2edb...@hotmail.com wrote: It costs me a bit to go back in time as these issues are already from some time back.. Let me try to give some input on these points. 2) I don't fully understand what the problem is here. Could you give an example that shows that it breaks? It's actually worse than I thought. If I add a type parameter to HandlerManager, I get something like class HandlerManagerSource { ... } But I have no way to specify the source type when it's declared in Widget: class Widget { HandlerManager??? handlerManager; } The Source type parameter would force me to declare a separate HandlerManager field in each subclass of Widget. But then I can't subclass a widget and get the source type correct -- I'd need *another* handlerManager field. 3) Ok, let me give an example and hope I have some luck here... ;) I remember we had this same discussion about primitive-simple Widget interfaces, you asked me the same thing (together with Bruce), I gave some concrete interfaces.. and never heard anyting :(... My app is very simple in layout: a menu on the left and the content on the right. You can navigate to another piece of content by clicking on the next/prev button in the content screen part or by clicking in the menu. If the user navigates away from the current content screen (by clicking next/previous... or the menu), and the current shown content isn't valid, he will be asked for a confirmation. If yes, the action (=going to the new content and saving the current shown content) will be performed, if no, the action is canceled and he stays on the same content screen. I implement this through an interceptor (aynchrone in this case) that will take care of the confirmation and some other
[gwt-contrib] Event model improvements ?
Hellu, I am porting my app to 1.6.4 and bounce my head against a few issues of the new event model. At first, this wouldn't be a big issue as long as you can add your own modifications, but I can't. What restrict me is to inject my own HandlerManager such that I can add my own behavior like adding an interceptor (optional: async interceptor), checks like maximum, duplicates, changing the source, etc... :(.. Why isn't it possible to be able to change the HandlerManager, what is the idea behind this? How I make it work now: extends all basic widgets like Label en TextBox and override the add**Listeners(...) method to bypass them to my own HandlerManager, which is contained in a so called Observer object. The overridden widget also overriddes the onBrowserEvent method and pass it on to the Observer object that will inform the listeners... This is very cumberslume and I hoped I would be able to solve it in the new event model. But I still can't and have to do it with a lot of code around it to make it work which isn't very friendly ofcouse... I noticed a few more disadvantages of the new event model that I posted here: http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/7d4e53c26cac6ae2# The related enhancement request: http://code.google.com/p/google-web-toolkit/issues/detail?id=3628q=HandlerManager If I read the announcements of the new event model it has all kind of advantages like the less code that is needed. However, this is what I experience like explained above. Does the gwt dev team look at this pratical issues and how it will exactly be used in complex systems ?... I am sorry, I know that the gwt dev team is doing their best but I sometimes have my doubts about that as I already had previous discusssions about strange usage of the gwt code, for example: the lack of some primitive interfaces. I understand that the gwt dev team wants to overcome a lock-in situation, but please realize that on the otherside it leads to strange (large) code to implement complex functionality which normally in swing or swt isn't that difficult. Just my thoughts, Ed --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: New shopping new life!
He Joel, Sorry for the trouble. Last night I came home and all of sudden my whole hotmail was changed and got all kind of failed mail deliveries :(... Yep, changed my password already. -- Ed --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: weak listener in GWT?
He Miroslav, Thanks for the tip: listeners to a container class that also implements the listener. Then I considered it as well, it's kind of categorizing the listeners, but doesn't work in my case. Le me explain: the screen consists of all kind o wizard kind of screens that the user can browse between. Each screen consists of maybe 20 form fields with checkboxes and textbox question. If a user then changes a checkbox half way, all next form field and all next wizard screen are removed. So the listeners in the next screen can easily be removed by removing the container of the listener category, however the listeners of the form fields in the same screen can't be removed in that way as some listeners need to stay untouched (the ones of the form field above the changed form field). BTW: I was thinking in a kind of Listener tree, whereby a node is a listener container that bubbles down the event to his leaves But, it seems to work fine now. BTW: I was looking at your gwt-rocket work. It contains some nice impressive work :) (Especially the way you use the gwt generators if very nice). Good work. Myself I always just a bit afraid to create a lock-in situation if the library isn't supported anymore or isn't up2date with the next gwt release (my experience in the past). So I am a bit careful with it. -- Ed --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: weak listener in GWT?
Hi Hiho, Thanks for your reaction. I don't want to sound (too) arrogant, but your solution is way to simple in my case (I wish I could use it). Because of the complex requirements I have to meet, I have several layers on top of basic widgets. That is: on the level I want to do some cleanup, these widgets are way out of scope (and I have too many widgets below). That is also desired behavior as on the level I want to do some cleanup, I don't want to directly see these widgets anymore as I am in another problem scope. I did some more prototyping and even my above suggestion doesn't solve my problem entirely as I sometimes want to remove part of the listeners that belong to a category. What I will do now: Like explained above: I have my own Form that contains Form field (these are the ones that wrap the basic widgets). These form fields (general gwt things) contain all kind of default behavior: validation, dirty checking, resetting, validation handling, etc.. (I have all kind of general form field for strings, birthday, datepicker, group of checkboxes, etc...) I will add a method to the Form field beforeRemove () that will always called by his managing Form just before removing (detaching) the form field of the Form, that gives the form field a change to do some cleanup. That is: when removing widgets/form field of the Form, I always do this trhough the manging Form. I will then add an extra method to the form field: addRemover (HasDestroy destroy), such that I can add things that need to be called by the Form field when beforeRemove() is called. In my builder I can then add instances to the Form field that need to do some cleanup. I think this is an elegant and nice solution, don't you think ? Da, I do miss the Weak Listener from SWT/Swing in cases like this... (It's back to the stoneage to do everyting yourself. Btw: don't get me wrong, I am not blaming GWT for this it's simple javascript that doesn't support this all) I would love to hear experiences of other developers have bounced their head against this issue. -- Ed --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: weak listener in GWT?
The solution that I suggest above, seem to work fine. BTW: I also had another look at the solution suggested by MiroSlav, but that is a technical soution that isn't correct in my case. His solution was to remove the global model listeners when the widget got detached. However, I can easily detach a widget/panel from one form and connect it to another form, which in my case is completely legal, but will result in correct behavior as the listeners are removed :(. So I solved it in a functional way by adding listeners to my Form Fields that are informed about form field removal/insertions. These listeners are added to the Form Field. I also have a Form listener that receives these kind of notifications, but couldn't be used in the form field builder as Form isn't know there, where as the Form field is. I hope it's of some use to others. -- Ed --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] More interfaces part 2
Hellu, I would like to know whtat the current status is of incoparating more basis interface in GWT? We talked about this a long time ago, but there more important issues then: http://groups.google.com/group/Google-Web-Toolkit-Contributors/browse_thread/thread/2aad0c3459e2c7f/cd59f6b35714ed31?lnk=gstq=more+interfaces I still keep on bouncing my head against these kind of interface issues: Below another example, which I hope would give some more priority to the issue: I need a general TextWidget that extends/implements from Widget and implements HasText, HasHtml. I thought I could easily solve this with Generics... Not.. really (see below). I want to return a Widget as result of a method that creates a Widget that implements HasHtml/HasText. I tried something like this: W extends Widget HasText HasHTML CmsFormatResultTextW create (String item); But calling this method isn't possible as the compiler complaints that Widget isn't a valid substitute. Body example: return new HTML(aaa); Which isn't correct as the compiler also complaints about not able to convert HTML to W... To solve this, I think I need a basis Widget interface instead of a Widget class. Please some feedback/advice on this. -- Ed --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: weak listener in GWT?
He John, Thanks for your answer. Not very unexpected, but I was hoping I missed something. This means that I have to do some more work when removing objects. My situation: I have pages that make up a wizard-like application (part of the application). The pages contain form field where the user fills in his name, social nr, etc.. When he goes back in the wizard tree and changes his birthday for example: other form fields on other pages are removed. However, they have a bunch of listeners subscribed to a global data model. Because of all the nested objects, it's easy to forget unregistering a listener. Basically what I do now (and have to do more): before making a form field variable NULL, call the formField.remove() method, that he forwards to his nested objects, and so on A bit cumbersome, but I don't see no other way, do you ?? -- Ed --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: DatePicker DatePickerComponent protected ?
Ahhh the famous lock-in reason. Yep, understandable... --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---