Created
April 4, 2010 00:25
-
-
Save takeru/354965 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| dubyc = "~/tmp/src_clones/duby/bin/dubyc" | |
| javac = "javac" | |
| classpath = [ | |
| "~/tmp/appengine-java-sdk-1.3.2/lib/shared/geronimo-servlet_2.5_spec-1.2.jar", | |
| "~/tmp/appengine-java-sdk-1.3.2/lib/impl/appengine-api.jar", | |
| "~/tmp/appengine-java-sdk-1.3.2/lib/impl/appengine-api-stubs.jar" | |
| ].join(":") | |
| Dir.chdir 'dubysrc' | |
| #system "CLASSPATH=#{classpath} #{dubyc} fwspin/HelloDubyServlet.duby" | |
| #system "CLASSPATH=#{classpath} #{dubyc} fwspin/HelloDubyFilter.duby" | |
| case ARGV[0] | |
| when "duby" | |
| system("rm fwspin/*.class") | |
| system "CLASSPATH=#{classpath} #{dubyc} fwspin/ForwardSpinupFilter.duby" | |
| when "java" | |
| system "CLASSPATH=#{classpath} #{dubyc} -java fwspin/ForwardSpinupFilter.duby" | |
| s = File.read("fwspin/ForwardSpinupFilter.java") | |
| s.sub!("FetchOptions$Builder", "FetchOptions.Builder") | |
| s.sub!("package fwspin;", "package fwspin;\nimport com.google.appengine.api.urlfetch.FetchOptions;") | |
| s.sub!("public static void main(java.lang.String[] argv) {", "") | |
| File.open("fwspin/ForwardSpinupFilter.java", "w"){|f| f.write(s) } | |
| when "javac" | |
| system("rm fwspin/*.class") | |
| system "CLASSPATH=#{classpath} #{javac} -Xlint:unchecked fwspin/ForwardSpinupFilter.java" | |
| when "jar" | |
| system "LANG=C jar -cvf ../WEB-INF/lib/fwspin.jar fwspin/*.class" | |
| else | |
| raise "ruby build_duby.rb duby|java|javac|jar" | |
| end | |
| Dir.chdir '..' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import javax.servlet.http.HttpServletRequest | |
| import javax.servlet.http.HttpServletResponse | |
| import javax.servlet.Filter | |
| import java.util.Date | |
| import java.util.ArrayList | |
| import java.net.URL | |
| import java.net.MalformedURLException | |
| import java.io.IOException | |
| import com.google.appengine.api.urlfetch.URLFetchService | |
| import com.google.appengine.api.urlfetch.FetchOptions | |
| import "FetchOptionsBuilder", "com.google.appengine.api.urlfetch.FetchOptions$Builder" | |
| import com.google.appengine.api.urlfetch.HTTPHeader | |
| import com.google.appengine.api.urlfetch.HTTPRequest | |
| import com.google.appengine.api.urlfetch.HTTPResponse | |
| import com.google.appengine.api.urlfetch.URLFetchServiceFactory | |
| import com.google.appengine.api.urlfetch.HTTPMethod | |
| class ForwardSpinupFilter; implements Filter | |
| def initialize | |
| end | |
| def init(conf) | |
| {:return=>void} | |
| @counter = 0 | |
| @load_counter = 0 | |
| @jruby_loaded = false | |
| @spinup_path = "/spinup" | |
| log("ForwardSpinupFilter:init") | |
| end | |
| def doFilter(_request, _response, chain) | |
| {data=>byte[], :return=>void} | |
| request = HttpServletRequest(_request) | |
| response = HttpServletResponse(_response) | |
| @counter += 1 | |
| log("#{@counter} : "+request.getRequestURL.toString) | |
| if 2<=@load_counter || is_spinup_url(request) | |
| # @load_counter == 0 => load jruby | |
| # @load_counter == 1 => load rails | |
| # @load_counter == 2 => load app and run! | |
| chain.doFilter(request, response) | |
| # if success | |
| @load_counter += 1 | |
| # else | |
| # timeout etc. instance is bloken? | |
| # end | |
| nil | |
| else | |
| kick_spinup_url(request) | |
| # forward request to active instance | |
| fetched = url_fetch(request) | |
| # Thread.sleep(2000) rescue nil | |
| # copy headers | |
| fetched.getHeaders.each do |_header| | |
| header = HTTPHeader(_header) | |
| response.setHeader(header.getName, header.getValue) | |
| end | |
| # copy body | |
| os = response.getOutputStream | |
| os.write(fetched.getContent) | |
| os.flush | |
| nil | |
| end | |
| end | |
| def destroy | |
| {:return=>void} | |
| log("destroy") | |
| end | |
| # http://code.google.com/intl/en/appengine/docs/java/javadoc/com/google/appengine/api/urlfetch/package-summary.html | |
| def url_fetch(request:HttpServletRequest) | |
| throws MalformedURLException, IOException | |
| url = request.getRequestURL | |
| q = request.getQueryString | |
| if q | |
| url.append("?").append(q) | |
| end | |
| data = "".getBytes # TODO post | |
| fs = URLFetchServiceFactory.getURLFetchService | |
| opt = FetchOptionsBuilder.disallowTruncate.doNotFollowRedirects.setDeadline(double(5.0)) | |
| req = HTTPRequest.new(URL.new(url.toString), HTTPMethod.valueOf(request.getMethod), opt) | |
| # each_header(request) do |name,value| | |
| # #addHeader(header) | |
| # puts key, value | |
| # end | |
| #todo setPayload(data) | |
| fs.fetch(req) # HTTPResponse | |
| end | |
| def is_spinup_url(request:HttpServletRequest) | |
| # log "@spinup_path: #{@spinup_path}" | |
| # log "PathInfo : #{request.getPathInfo || '(null)'}" | |
| # log "ContextPath : #{request.getContextPath || '(null)'}" | |
| log "is_spinup_url:ServletPath=#{request.getServletPath || '(null)'}" | |
| return @spinup_path.equals(request.getServletPath) | |
| end | |
| def kick_spinup_url(request:HttpServletRequest) | |
| throws MalformedURLException | |
| fs = URLFetchServiceFactory.getURLFetchService | |
| url = "http://"+request.getServerName | |
| url += ":#{request.getServerPort}" if 80 != request.getServerPort | |
| url += @spinup_path | |
| log "kick_spinup_url: #{url}" | |
| fs.fetchAsync(URL.new(url)) | |
| end | |
| ## * Can I use yield? | |
| ## * Can I use each for java.util.Enumeration | |
| # def each_header(request:HttpServletRequest) | |
| # headers = ArrayList.new | |
| # names = request.getHeaderNames | |
| # while(names.hasMoreElements) do | |
| # name = String(names.nextElement) | |
| # values = request.getHeaders(name) | |
| # while(values.hasMoreElements) do | |
| # value = String(values.nextElement) | |
| # yield(name) | |
| # end | |
| # end | |
| # end | |
| def log(s:String) | |
| {:return=>void} | |
| puts(Date.new.toString + " : " + s) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| I am using self-build duby. | |
| Source code(bitescript, jruby, duby) is from github, yesterday. | |
| 1. imcomplete main method: | |
| "public static void main(java.lang.String[] argv) {" | |
| I removed it in build_duby.rb. | |
| s.sub!("public static void main(java.lang.String[] argv) {", "") | |
| 2. How to use inner class | |
| I want to use http://code.google.com/intl/en/appengine/docs/java/javadoc/com/google/appengine/api/urlfetch/FetchOptions.Builder.html this class. | |
| Now, I write duby like: | |
| import "FetchOptionsBuilder", "com.google.appengine.api.urlfetch.FetchOptions$Builder" | |
| And compile to java and patch: | |
| s.sub!("FetchOptions$Builder", "FetchOptions.Builder") | |
| s.sub!("package fwspin;", "package fwspin;\nimport com.google.appengine.api.urlfetch.FetchOptions;") | |
| Can I use better way? | |
| 3. VerifyError with dubyc | |
| "duby -> class" directly compiled class is not work. | |
| "duby -> java -> patch -> javac" is work well. | |
| 4. No main found | |
| in examples: | |
| % duby fib.duby | |
| No main found | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # VerifyError with "dubyc" | |
| Apr 4, 2010 12:02:57 AM com.google.apphosting.utils.jetty.JettyLogger warn | |
| WARNING: failed ForwardSpinupFilter: java.lang.VerifyError: (class: fwspin/ForwardSpinupFilter, method: url_fetch signature: (Ljavax/servlet/http/HttpServletRequest;)Lcom/google/appengine/api/urlfetch/HTTPResponse;) Expecting to find object/array on stack | |
| Apr 4, 2010 12:02:57 AM com.google.apphosting.utils.jetty.JettyLogger warn | |
| WARNING: failed com.google.apphosting.utils.jetty.DevAppEngineWebAppContext@1142196{/,/Users/takeru/..../versions/fwspin}: java.lang.VerifyError: (class: fwspin/ForwardSpinupFilter, method: url_fetch signature: (Ljavax/servlet/http/HttpServletRequest;)Lcom/google/appengine/api/urlfetch/HTTPResponse;) Expecting to find object/array on stack | |
| Apr 4, 2010 12:02:57 AM com.google.apphosting.utils.jetty.JettyLogger warn | |
| WARNING: failed JettyContainerService$ApiProxyHandler@13ada: java.lang.VerifyError: (class: fwspin/ForwardSpinupFilter, method: url_fetch signature: (Ljavax/servlet/http/HttpServletRequest;)Lcom/google/appengine/api/urlfetch/HTTPResponse;) Expecting to find object/array on stack | |
| Apr 4, 2010 12:02:57 AM com.google.apphosting.utils.jetty.JettyLogger warn | |
| WARNING: Error starting handlers | |
| java.lang.VerifyError: (class: fwspin/ForwardSpinupFilter, method: url_fetch signature: (Ljavax/servlet/http/HttpServletRequest;)Lcom/google/appengine/api/urlfetch/HTTPResponse;) Expecting to find object/array on stack | |
| at java.lang.Class.getDeclaredConstructors0(Native Method) | |
| at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389) | |
| at java.lang.Class.getConstructor0(Class.java:2699) | |
| at java.lang.Class.newInstance0(Class.java:326) | |
| at java.lang.Class.newInstance(Class.java:308) | |
| at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153) | |
| at org.mortbay.jetty.servlet.FilterHolder.doStart(FilterHolder.java:92) | |
| at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50) | |
| at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:662) | |
| at org.mortbay.jetty.servlet.Context.startContext(Context.java:140) | |
| at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250) | |
| at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517) | |
| at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467) | |
| at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50) | |
| at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130) | |
| at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50) | |
| at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130) | |
| at org.mortbay.jetty.Server.doStart(Server.java:224) | |
| at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50) | |
| at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:185) | |
| at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:146) | |
| at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:219) | |
| at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:162) | |
| at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48) | |
| at com.google.appengine.tools.development.DevAppServerMain.<init>(DevAppServerMain.java:113) | |
| at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:89) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment