Skip to content

Instantly share code, notes, and snippets.

@takeru
Created April 4, 2010 00:25
Show Gist options
  • Select an option

  • Save takeru/354965 to your computer and use it in GitHub Desktop.

Select an option

Save takeru/354965 to your computer and use it in GitHub Desktop.
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 '..'
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
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
# 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