Hello fellow developers,
Ok, so I've finally been able to upload my SmartGWT app into GAE.
First of all, if you try to upload your SmartGWT app into GAE without any changes you'll notice an error like:
This happens because there are probably more than 1000 files in your generated smartgwt 'sc' dir.
So far, the proposed solution to this problem was to use another host (like Amazon S3) for the 'sc' static files. You have a thread explaining how to do it here: http://forums.smartclient.com/showthread.php?t=5105
Another approach is to zip the contents of the 'sc' dir and have the needed files unzipped on the fly using a servlet. This was originally proposed by a google developer during the last GAE IRC chat. (This is also a similar solution to the deployment of SmartGWT apps in GAE-Python, as suggested in other threads of this forum.)
So, how to do it:
1. Zip your 'sc' dir and place the produced file in your 'war' dir.
Note that the zip file must be compressed. The uncompressed file will have more than 10 MB and that will also originate an error during upload to GAE.
2. Edit your 'appengine-web.xml' file and exclude all 'sc' files from your app resources. Like this:
Note: you must substitute 'myappname' by your app name.
Another Note: I don't know why, sometimes the request URI for 'sc' begins with '/sc/...' and other times with '/myappname/sc/...'. Maybe someone can explain this. My solution was to exclude both.
3. In your 'web.xml' file, create a new servlet that will catch all requests to 'sc':
4. Implement the Servlet:
5 - Upload your app!
If all goes well you will be able to see your app in GAE.
There are some performance tuning improvements to do. If you have any ideas please share them!
Happy coding...
Ok, so I've finally been able to upload my SmartGWT app into GAE.
First of all, if you try to upload your SmartGWT app into GAE without any changes you'll notice an error like:
Code:
400 Bad Request Max number of files and blobs is 1000.
So far, the proposed solution to this problem was to use another host (like Amazon S3) for the 'sc' static files. You have a thread explaining how to do it here: http://forums.smartclient.com/showthread.php?t=5105
Another approach is to zip the contents of the 'sc' dir and have the needed files unzipped on the fly using a servlet. This was originally proposed by a google developer during the last GAE IRC chat. (This is also a similar solution to the deployment of SmartGWT apps in GAE-Python, as suggested in other threads of this forum.)
So, how to do it:
1. Zip your 'sc' dir and place the produced file in your 'war' dir.
Note that the zip file must be compressed. The uncompressed file will have more than 10 MB and that will also originate an error during upload to GAE.
2. Edit your 'appengine-web.xml' file and exclude all 'sc' files from your app resources. Like this:
Code:
<!-- By default all WAR files are static except WEB-INF --> <!-- This overrides the default --> <static-files> <!-- Exclude smartgwt files from the list of static files --> <exclude path="/sc/**.*" /> <exclude path="/myappname/sc/**.*" /> </static-files> <!-- By default all WAR files are also resource files including WEB-INF --> <!-- This overrides the default --> <resource-files> <!-- Exclude smartgwt files from the list of resource files --> <exclude path="/sc/**.*" /> <exclude path="/myappname/sc/**.*" /> </resource-files>
Another Note: I don't know why, sometimes the request URI for 'sc' begins with '/sc/...' and other times with '/myappname/sc/...'. Maybe someone can explain this. My solution was to exclude both.
3. In your 'web.xml' file, create a new servlet that will catch all requests to 'sc':
Code:
<!-- SmartGWT static resources servlet --> <servlet> <servlet-name>scServlet</servlet-name> <servlet-class>org.myapp.server.ScServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>scServlet</servlet-name> <url-pattern>/sc/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>scServlet</servlet-name> <url-pattern>/myappname/sc/*</url-pattern> </servlet-mapping>
Code:
package org.myapp.server; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ScServlet extends HttpServlet { private static final Logger log = Logger.getLogger(ScServlet.class.getName()); /** * This servlet receives all '/sc/*' requests according to a rule defined in * 'web.xml'. It looks for the necessary resource in 'sc.zip' which should * be present in the application classpath. */ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { // Sometimes the request URI begins with '/sc' and other times with // '/myappname/sc', so we always remove '/myappname' from the request URI String requestedURI = req.getRequestURI().replaceFirst("/myappname", ""); // At this point requestedURI begins with '/sc/...' but the zip file entries // begin with 'sc/...', so we remove the first '/' requestedURI = requestedURI.substring(1); log.info("Requested URI '" + req.getRequestURI() + "' converted to '" + requestedURI + "'"); // search for resource ZipInputStream in = new ZipInputStream(new FileInputStream("sc.zip")); ZipEntry entry; while ((entry = in.getNextEntry()) != null) { if (requestedURI.equals(entry.getName())) { // resource found // redirect it to output stream OutputStream out = resp.getOutputStream(); byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); out.close(); log.info("Requested '" + requestedURI + "' found in zip file entry: " + entry.getName()); return; } } log.severe("Requested '" + requestedURI + "' not found in zip file!"); } }
If all goes well you will be able to see your app in GAE.
There are some performance tuning improvements to do. If you have any ideas please share them!
Happy coding...
Comment