Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    #16
    Smartgwt on google app engine

    I just published a tutorial on deploying a simple spring MVC application on Google App Engine. I am providing an example and the source code.

    http://javagoogleappspot.blogspot.com/
    Last edited by the_dudero1; 21 Oct 2009, 03:51.

    Comment


      #17
      In your app.yaml file, simply include the following line:

      resource_files:
      - exclude: /yourappname/sc/**.*

      It basically excludes all SmartClient files from resources, and deployment goes through just fine. Now have both GXT and SmartGWT working on AppEngine without much problems.

      Hope this helps.

      Comment


        #18
        I just tried to use the Google App Engine server and also had more than 3000 files, when using smartgwt. I noticed that in the current solution server side caching is used, but none on client side. I modified the code to enable client side caching by setting header ETag and Cache-control

        Code:
        import java.io.ByteArrayOutputStream;
        import java.io.FileInputStream;
        import java.io.FileNotFoundException;
        import java.io.IOException;
        import java.io.InputStream;
        import java.security.DigestInputStream;
        import java.security.MessageDigest;
        import java.security.NoSuchAlgorithmException;
        import java.util.Collections;
        import java.util.logging.Logger;
        import java.util.zip.ZipEntry;
        import java.util.zip.ZipInputStream;
        
        import javax.cache.CacheException;
        import javax.cache.CacheManager;
        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());
        	private static String identifier;
        	
        	/**
        	 * 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);
        		
        		requestedURI = requestedURI.replaceAll("//", "/");
        
        		log.info("Requested URI '" + req.getRequestURI() + "' converted to '" + requestedURI + "'");
        
        		try {
        			// Client side caching 
        			resp.setHeader("ETag", getIdentifier());
        			resp.setHeader("Cache-Control", "public, max-age=2592000"); // Client cache age 30 days
        			
        			// Load from server side cache
        			resp.getOutputStream().write(getResourceFromCache(resp,requestedURI));
        		} catch (CacheException e) {
        			resp.getOutputStream().write(getResourceFromZip(resp,requestedURI));
        		}
        	}
        	
        	/**
        	 * 
        	 * @return md5 string for current sc.zip
        	 */
        	private String getIdentifier()
        	{
        		if (identifier == null)
        		{
        			InputStream is = null;						
        			try {
        				// Generate md5 digest from file
        				MessageDigest md = MessageDigest.getInstance("MD5");
        				is = new FileInputStream("sc.zip");
        				int buffersize = is.available();
        				byte[] buffer = new byte[buffersize];				
        				is = new DigestInputStream(is, md);
        				while (is.read(buffer) > 0);
        				byte[] digest = md.digest();
        				identifier = new String(digest);
        			} catch (FileNotFoundException e)
        			{
        				e.printStackTrace();
        			} catch (NoSuchAlgorithmException e)
        			{
        				e.printStackTrace();
        			} catch (IOException e)
        			{
        				e.printStackTrace();
        			} finally
        			{
        				try
        				{
        					is.close();
        				} catch (Exception e)
        				{
        					e.printStackTrace();
        				}
        			}
        
        		}
        			return identifier;
        	}
        
        	private byte[] getResourceFromCache(HttpServletResponse resp,String key)
        	  throws CacheException, IOException {
        
        	  javax.cache.Cache cache = CacheManager.getInstance().getCacheFactory().createCache(Collections.emptyMap());
        	  byte[] resource = (byte[]) cache.get(key);
        
        	  if (resource == null) {
        	     resource = getResourceFromZip(resp,key);
        	     cache.put(key, resource);
        	  }
        
        	  return resource;
        	}
        
        	private byte[] getResourceFromZip(HttpServletResponse resp,String requestedURI) throws FileNotFoundException, IOException {
        		// 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
        				ByteArrayOutputStream out = new ByteArrayOutputStream();
        				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 out.toByteArray();
        			}
        		}
        
        		log.severe("Requested '" + requestedURI + "' not found in zip file!");
        		return null;
        	}
        
        }

        Comment


          #19
          Googling on the web, SmartGWT + AppEngine appears to work, is there any proper guidance on this? Unless otherwise I'm looking to deploy a SmartEngine App on the AppEngine.

          Comment


            #20
            Originally posted by planetblix
            Googling on the web, SmartGWT + AppEngine appears to work, is there any proper guidance on this? Unless otherwise I'm looking to deploy a SmartEngine App on the AppEngine.
            None that I'm aware of. Basically it depends on what features of smartgwt you want to use, if you just want to use the controls for the UI (client side) you're pretty much fine.

            Comment


              #21
              OK, thanks. If I get something working, I'll write something up. Quick question, where in the folder structure do I place the ScServlet.java file?

              Comment


                #22
                Originally posted by planetblix
                OK, thanks. If I get something working, I'll write something up. Quick question, where in the folder structure do I place the ScServlet.java file?
                Forget about ScServlet.java, it was used because of a limitation on the number of files but it isn't necessary anymore.

                Comment


                  #23
                  I get the same time out 505 error anyway, I think it's just the AppEngine failing somewhere, will try a few more times.

                  Comment

                  Working...
                  X