As far as I know the "user.agent" property in the Google Web Toolkit .gwt.xml file specifies the targets for the Java to Java Script translation. Because the hosted mode still runs Java and not Javascript I don't understand why google chrome complains that the "user.agent" value is not set correctly. Even more strange, it keeps complaining even if I add "safari" to it with <set-property name="user.agent" value="gecko1_8,safari" />.
What can I do here?
I use GWT version 2.3.0 and GXT version 2.2.5.
DevMode does not compile to JavaScript but still has to honor deferred binding rules, and many of them are based on the user.agent property, so it must be correctly set.
The user.agent property value is determined by some script snippet generated in the so-called selection script (the *.nocache.js file), and the content of this script can depend on the set-propertys you have in your GWT module(s).
For instance, if you compile a GWT module with <set-property name="user.agent" value="gecko1_8" />, the user.agent property will be hard-coded to the gecko1_8 value in the *.nocache.js.
If you later run DevMode, unless it thinks it has to overwrite the existing *.nocache.js, it'll use it; so running the app using Chrome when the *.nocache.js was generated for gecko1_8 only will cause an error similar to:
com.google.gwt.core.client.JavaScriptException: (TypeError): Property 'user.agent' of object is not a function
In case you compiled for several browsers, but then run DevMode with a module only for gecko1_8, then the DevMode will use the property provider found in the *.nocache.js to determine the actual user agent being used (woul dbe safari for Chrome), and will compare it with the one determined from the module (hard-coded here to gecko1_8), and will then warn you that they don't match (and as such that you app might dysfunction: the code will use DOMImplMozilla for instance, whereas DOMImplSafari should have been used in Chrome).
So, to fix this, either delete the *.nocache.js file so DevMode will have to generate a new one, or recompile your app with a module whose user.agent values match the browser you'll use in DevMode.
Related
Keep getting CSP errors: "Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'"
The problem is probably due to HTML files generated by GWT which contain inline JS.
UPD: Changing to manifest version 1 helped, but this is a temporary workaroud, as Chrome 21 complains that it will no longer be supported.
UPD2: <add-linker name="xsiframe" /> does not help either
GWT 2.5.1 has finally fixed this problem. The release notes documenting this are here:
https://developers.google.com/web-toolkit/release-notes#Release_Notes_2_5_1
and they state that:
"Apps built with DirectInstallLinker should work in a page where inline scripts are forbidden (e.g. a Chrome extension)"
This means that it is now possible to use DirectInstallLinker to link your Chrome packaged app in a manner that satisfies the new security requirements of manifest version 2 regarding inline scripts. That is, by using DirectInstallLinker to link your app with GWT 2.5.1 selected as your GWT version, GWT will not place any script elements inline in its generated Javascript, and thus the new manifest version 2 requirement that there be no inline scripts will not be violated.
I have found that SingleScriptLinker also seems to work for my own app; however, Issue 7685 warns against using the SingleScriptLinker because "This generates a $doc.write line which is forbidden in packaged apps." I am using DirectInstallLinker myself.
Here is the Javadoc for DirectInstallLinker:
http://google-web-toolkit.googlecode.com/svn/javadoc/2.5/com/google/gwt/core/linker/DirectInstallLinker.html
To use this linker, you can include the following in your *.gwt.xml file:
<define-linker name="dil" class="com.google.gwt.core.linker.DirectInstallLinker"/>
<add-linker name="dil" />
(dil can be replaced by anything you choose, so long as there are no dashes or other illegal characters).
You will need to select GWT 2.5.1 as your version of GWT. If you're using an older version of GWT in an out-of-date version of Eclipse such as Ganymede (as I was), you'll have to upgrade to at least Helios and then import your project to your new Eclipse environment. The archive URLs for the Google Plugin for Eclipse that can be used for the latest three Eclipse versions can be found here:
https://developers.google.com/eclipse/docs/download
With the above in place, you should be able to set
"manifest_version": 2
in your manifest.json file and not experience any errors due to GWT-generated inline Javascript. This should allow your Chrome Web app to be acceptable to the Chrome Web Store (which now requires manifest version 2 for any new apps or for updates to present apps), so long as there are no other issues.
EDIT: new GWT bug reported: http://code.google.com/p/google-web-toolkit/issues/detail?id=7685, see also http://gwt-code-reviews.appspot.com/1838803/ which is related to this bug
In other words, it looks like, when fixed, you'll simply have to use the DirectInstallLinker (<add-linker name='direct_install'/>).
In the mean time, IIUC, you'd have to extend DirectInstallLinker and:
override getJsInstallLocation to return a copy a installLocaltionIframe.js without the $wnd part
override getModulePrefix to prepend var $wnd = $wnd || window.parent; to what's generated by super.getModulePrefix
I don't know CSP enough to give a complete answer, but the xsiframe linker is "customizable": create a class that extends com.google.gwt.core.linker.CrossSiteIframeLinker and overrides the appropriate methods, then use with a <define-linker> and <add-linker> in your *.gwt.xml.
For instance, getJsInstallLocation defaults to com/google/gwt/core/ext/linker/impl/installLocationIframe.js but there's a com/google/gwt/core/ext/linker/impl/installLocationMainWindows.js alternate implementation.
Similarly (and probably more importantly), getJsInstallScript defaults to com/google/gwt/core/ext/linker/impl/installScriptEarlyDownload.js but there's also a com/google/gwt/core/ext/linker/impl/installScriptDirect.js alternate implementation.
See http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java#204, http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/ and http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/core/Core.gwt.xml
Thanks to Thomas Broyer's advice. I created this GWT Linker. Now my GWT application runs perfectly as an Chrome Application (Tested on Chrome 32 and GWT 2.5.1).
public class CSPCompatibleLinker extends DirectInstallLinker {
#Override
protected String getJsInstallLocation(LinkerContext context) {
return "com/google/gwt/core/ext/linker/impl/installLocationMainWindow.js";
}
}
Dont forget to declare the Linker into your*.gwt.xml file:
<define-linker name="csp" class="com.sfeir.linker.CSPCompatibleLinker"/>
<add-linker name="csp" />
Manifest version 2 does not allow inline scripts. You need to make sure all scripts are linked instead and no JavaScript in HTML elements.
I have a litte web app which works properly when deployed to the App Engine in Eclipse.
However, I get an error when I want to deploy my app to my Tomcat server.
I copied the content of my war folder directly to the default ROOT folder of Tomcat.
Then I run my app on an external server inside Eclipse.
Everything works fine to that point - the app is loaded straight from the browser's cache.
Here comes the problem:
The google chrome development console says "Uncaught ReferenceError: function is not defined" when I click on some features of my app that are realized through JSNI on GWT side.
I understand that the error comes from a JS caller inside external JS code. The caller invokes a GWT client-side method/function (that's why it is not defined in the ext. JS code).
Any suggestions on how to solve this problem?
Do you have any extra modules that require external js files? Some modules require the js files to be included in the war and included in your root .html file. It could be the case that you are using a library that doesn't have the base js functions.
You can add this to your .gwt.xml file to turn on the stack trace.
<set-property name="compiler.stackMode" value="emulated"/>
<set-configuration-property name="compiler.emulatedStack.recordLineNumbers" value="true"/>
<set-configuration-property name="compiler.emulatedStack.recordFileNames" value="true"/>
You could also try the setUncaughtException handler to see exceptions that are being thrown in production mode. With the emulated stack trace turned on you should be able to get a backtrace that has line numbers for your code. It is not as good as development mode but very useful for debugging.
GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler()) {
#Override
public void onUncaughtException(Throwable cause) {
logger.log(Level.SEVERE, "OOPS", cause);
}
}
Note Make sure your logger is configured to use something you can access. Like firebug or remote logging servlet.
I currently use tomcat 7 in production and development mode using eclipse. You can configure a tomcat instance of the server in eclipse and use the "Run as WebApplication on External Server". This will allow you to see the exception in development mode.
Also make sure you don't have the ?gwt.codesvr=127.0.0.1:9997 if you are in production mode. This will cause problems too unless you have the development code server running.
Case
i'm trying to write a GWTTestCase for a certain class, used as a presenter for a history-browsing toolbar component i'm building.
Problem
one (or more) of the scripts apparently not being loaded for the jUnit testing environment. it all works fine when running the application (development mode), but when i try to run the test case, the application (web server as well as user agent) fails to load, and the following exception arouses (stacktrace is shortened for simplicity):
com.gargoylesoftware.htmlunit.ScriptException: Wrapped com.gargoylesoftware.htmlunit.ScriptException: Exception invoking jsxFunction_write at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:601) at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:537) at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:538) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:499) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:595) ... 41 more
...
Caused by: com.gargoylesoftware.htmlunit.ScriptException: Wrapped com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: "Raphael" is not defined. (http://192.168.10.32:3692/com.gigaspaces.admin.webui.Gs_webui.JUnit/dracula/dracula_graffle.js#18) (http://192.168.10.32:3692/com.gigaspaces.admin.webui.Gs_webui.JUnit/com.gigaspaces.admin.webui.Gs_webui.JUnit.nocache.js#16) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:601)
Relevant sources
here is the (ridiculously simple) GWTTestCase used:
public class HistoryBrowserTest extends GWTTestCase {
#Override
public String getModuleName() {
return "com.gigaspaces.admin.webui.Gs_webui";
}
public void testHistoryBrowser() {
assertTrue(true);
}
}
Dependencies / context information
jUnit 4.10 is used as an external jar - and referenced successfully by the classpath and the .gwt.xml file is inheriting jUnit from GWT (<inherits name="com.google.gwt.junit.JUnit" />) the jUnit module is no longer inherited as the GWT team instructs not to - extending GWTTestCase will inherit it automatically.
i am using Raphael-GWT as a separate module. this module is also referenced in the main module's .gwt.xml file, and running fine under all other circumstances (development / production mode).
What have i tried
simplifying the case, e.g. stripping down the test case as seen above.
verifying inherited modules in the deployment descriptors.
varying jUnit's version, i.e. running both under V3 or V4, and manually compiled on each change.
looked up on google, as well as here on stackoverflow, with no avail.
More relevant information
Raphael lib is being used for a GWT wrapper i wrote for Dracula (a JS graph visualization library) so dracula_graffle.js originates there. enclosed is the .gwt.xml file source for a reference:
<module rename-to="gs_webui">
<inherits name="com.google.gwt.user.User" />
<!-- Other module inherits -->
<inherits name="com.extjs.gxt.ui.GXT" />
<inherits name="org.highchartsgwt.HighCharts" />
<inherits name="gwtupload.GWTUpload" />
<inherits name="com.hydro4ge.raphaelgwt.RaphaelGWT" />
<inherits name="com.gigaspaces.gauge.Gs_gauges" />
<inherits name="com.gigaspaces.graphs.Gs_graphs" />
<inherits name="com.gigaspaces.svgcomponents.Gs_svg_components" />
<inherits name="com.javaconstructors.colorpalette.Color_palette" />
<inherits name="com.gigaspaces.jquerywidgets.Gs_jquery_widgets" />
<inherits name="com.gigaspaces.codemirror_gwt.CodeMirror_GWT"/>
<inherits name="com.google.gwt.i18n.I18N"/>
<inherits name="com.google.gwt.query.Query" />
<!-- I18N stuff, log configurations, and so forth... -->
<entry-point class="com.gigaspaces.admin.webui.client.Gs_webui" />
<!-- further source folder inherits... -->
</module>
How is Raphael loaded? It could be that the js file is never being pulled in to the html page being run in htmlunit.
Caused by: com.gargoylesoftware.htmlunit.ScriptException: Wrapped com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: "Raphael" is not defined. (http://192.168.10.32:3692/com.gigaspaces.admin.webui.Gs_webui.JUnit/dracula/dracula_graffle.js#18) (http://192.168.10.32:3692/com.gigaspaces.admin.webui.Gs_webui.JUnit/com.gigaspaces.admin.webui.Gs_webui.JUnit.nocache.js#16)
This file doesn't appear to be used by RaphaelGWT, as it is not listed in their module file (seen here http://code.google.com/p/raphaelgwt/source/browse/trunk/src/com/hydro4ge/raphaelgwt/RaphaelGWT.gwt.xml).
This seems to be the source of your error - dracula_graffle.js (either line 18, or this is the 18th file loaded) cannot find the symbol Raphael, and since it is somehow required by your module, the app (in this case test) can't load without it. My quick guess is that it is either an HtmlUnit issue (HtmlUnit is what the gwt test cases run in, and only simulates a real browser) - you might try running this same test in a real browser, see http://code.google.com/webtoolkit/doc/latest/DevGuideTesting.html#Manual_Mode for more info. If that fails, then perhaps your app normally loads into an html page where some JS files have already been loaded, so this doesnt happen - those need to be loaded when testing the app as well, either using ScriptInjector in a setup method, or by adding them to your module file.
(After edits, comments)
Since the error occurred in manual mode as well, there isn't an error with htmlunit, but with dependencies in your code. From what appears to be a copy of dracula_graffle.js at http://code.google.com/p/synoptic/source/browse/synopticgwt/war/dracula_graffle.js?spec=svn2164f4b075bb0ed77f7b008bd113e04831196fec&r=2164f4b075bb0ed77f7b008bd113e04831196fec, line 18 is the first reference to Raphael, which should have defined when the raphael js file was loaded, which implies that it wasn't.
Running in manual mode with Firebug or the like running should show you an error in the console. Based on this, I think it is safe to say that something is different about the test case than the standard entrypoint+html page. The question is, what is different.
Are there any JS files, or script tags that run when the html page loads? GWTTestCases always run with just a very simple html page, and only load scripts defined in the module that you actually name in your .gwt.xml file. Are there any setup functions that are run as part of the entrypoint? Have you tried making a new, very simple html page, and writing a new, very simple EntryPoint for the module and using that instead? In the course of testing these things, I believe you will find some difference that is important in how your app works from how your test works.
If there isn't... the next annoying step is to run in manual mode again, with your app compiled in production model (see the same link, it should give details on how that might be done). Set firebug (or whatever tool you prefer) to stop on exceptions in Js, or simple set a breakpoint on line 18, when Raphael is used for the first time in dracula_graffle.js to see what scripts have loaded, and why Raphael isn't yet defined.
I have a GWT 2.4.0 website hosted in Jetty. When I browse this website using IE8 I get the following alert message:
ERROR: Possible problem with your *.gwt.xmi module file.
The compile time user.agent value (ie8) does not match the runtime user.agent
value (safari). Expect more errors.
Why does GWT think my runtime user agent is Safari? How can I let it know it's actually IE8? Am I right in suspecting that having the Chrome Frame plug-in installed in my IE8 has something to do with this?
Check your *gwt.xml files. Does it have something that looks like this:
<set-property name="user.agent" value="safari" />
That's telling it to only compile the safari version.
When GWT module is compiled with only one user.agent it doesn't check it in the bootstrap javascript, but loads directly that version. When that version checks the user.agent it finds (I guess) your Chrome frame and complains about its safari.
So... I guess you have only compiled your module with:
<set-property name="user.agent" value="ie8">
I should either check how ChromeFrame vs. GWT behaviour is... or simply add both user.agents and let module bootstrap load what's correct for your runtime environment.
<set-property name="user.agent" value="ie8,safari">
And of course I should check your ChromeFrame configuration to see what pages are loaded with it: all, none, some URLs, etc...
I'm ramping up on Vaadin and I'm getting this javascript alert whenever I try and run the demo apps.
GWT module 'com.vaadin.terminal.gwt.DefaultWidgetSet' may need to be recompiled
I've tried cleaning the project to no avail.
As I said, I'm ramping up so I'm sure there's some simple step I'm missing or a concept I haven't grasped.
I don't know anything about Vaadin, but there's a more general context in which this error occurs:
So long as you're testing in Eclipse, the dynamic coding of your app is still real Java coding being run in a JVM. This coding is made available through debugger that's accessible via a socket. You get a URL that looks like this:
http://127.0.0.1:8888/MyApp.html?gwt.codesvr=127.0.0.1:9997
with this codesvr thing being your eclipse-hosted debugger process for your Java code.
Before your app can run standalone, GWT has to translate your Java code to JavaScript; separate versions of the code are produced for each browser type (Firefox, WebKit, Opera, ...) and language that you want to support. Only once this is done can you access your app the usual way via
http://127.0.0.1:8888/MyApp.html
After weeks of running my app only in Eclipse, I'd managed to forget about the compiling-for-browsers step and wondered about the message. The way to fire up the compiler, if you're not using the Ant task, is to hit Google|GWT Compile in the project's context menu. That done, the JS in your app gets fleshed out and your app can run without Java on the client side.
And of course the message goes away.
It is a warning not an error. Does the app work? Otherwise you have to recompile the Vaadin widgetset. These might help too: http://vaadin.com/directory/help/using-vaadin-add-ons
Often this message meens:
you're missing the ?gwt.codesvr=127.0.0.1:9997 parameter in the URL (or have misspelled it).
your module uses the xs linker <add-linker name="xs" />. This is a known limitation and will be fixed in the future: Issue 4232: Allow Development Mode to work with XS Linker
You may need to clear the browser cache. It is possible that the compiled js that the browser is using is not the js that has most recently been compiled.
In Chrome you can see if the cached js is being used in the developer tools windows (ctrl + shift + i). In the size column it will say (from cache) instead of the actual size. You can then right click and clear the browser cache. ctrl + r to reload and the error should be gone.
Carl Smotricz is absolutely right.
Just Cleaning and Build Project on the topmost menu doesn't work.
You must use "Google | GWT Compile" on the context menu generated when right-clicking on your GWT project, prior to deployment.
The error may not be about not-adding "?gwt.codesvr=127.0.0.1:9997" at the end of host web page if he or she tried to deploy the GWT-based webapp on WAS external to Eclipse.
Server restart did the job for me.
I had tried clearing cache, clean and rebuild .. but i was still getting the same warning message.
Server restart made it reload all the stull from the latest compiled war.
It was a hit and trial and i am glad it worked :) :)