com.sun.grizzly.jruby.RubyAdapter Maven / Gradle / Ivy
package com.sun.grizzly.jruby;
import com.sun.grizzly.http.SelectorThread;
import com.sun.grizzly.pool.PoolAdapter;
import org.jruby.Ruby;
import org.jruby.RubyInstanceConfig;
import org.jruby.javasupport.JavaEmbedUtils;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.load.LoadService;
import org.jruby.util.ClassCache;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
/**
* An implementation of PoolAdapter to distribute JRuby runtimes.
*/
public class RubyAdapter implements PoolAdapter {
private final String railsRoot;
/**
* JRUBY_LIB directory
*/
private final String jrubyLib;
public RubyAdapter(String railsRoot, String jrubyLib) {
this.railsRoot = railsRoot;
this.jrubyLib = jrubyLib;
}
public Ruby initializeObject() {
ArrayList libs = new ArrayList();
libs.add("META-INF/jruby.home/lib/ruby/site_ruby/1.8");
ClassCache cache = new ClassCache(RubyAdapter.class.getClassLoader());
RubyInstanceConfig config = new RubyInstanceConfig();
File rdebugScript = configureRDebug(config);
config.setLoader(RubyAdapter.class.getClassLoader());
config.setClassCache(cache);
org.jruby.Ruby runtime = JavaEmbedUtils.initialize(libs, config);
return setupRails(runtime, rdebugScript);
}
public void dispose(Ruby dead) {
dead.tearDown();
}
public boolean validate(Ruby toCheck) {
return true; //Ruby instances can't be validated, so we return true. In general, Ruby instances shouldn't even be run with validation enabled
}
private Ruby setupRails(org.jruby.Ruby runtime, File rdebugScript) {
// long startTime = System.currentTimeMillis();
LoadService loadService = runtime.getLoadService();
if (rdebugScript != null) {
// synchronize io is optional
String iosynch = System.getProperty("glassfish.rdebug.iosynch");
if (iosynch != null && iosynch.length() > 0 && new File(iosynch).exists()) {
SelectorThread.logger().log(Level.FINEST,
"rdebug io synchronized by " + new File(iosynch).getAbsolutePath());
loadService.require(iosynch);
}
try {
SelectorThread.logger().log(Level.FINEST, "Initializing rdebug...");
runtime.runFromMain(
new java.io.BufferedInputStream(new FileInputStream(rdebugScript)),
rdebugScript.getAbsolutePath());
SelectorThread.logger().log(Level.FINE, "rdebug started for " + railsRoot);
} catch (Exception ex) {
SelectorThread.logger().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
}
} else {
// load rails
loadService.require(railsRoot + "/config/environment");
loadService.require("cgi/force_nph");
loadService.require("dispatcher");
}
IRubyObject responder = (JavaEmbedUtils.newRuntimeAdapter()).eval(runtime, getDispatcherString());
runtime.defineReadonlyVariable("$responder", responder);
return runtime;
}
private File configureRDebug(RubyInstanceConfig config) {
String rdebug = System.getProperty("glassfish.rdebug");
File rdebugScript = null;
if(rdebug != null && rdebug.length() > 0) {
SelectorThread.logger().log(Level.FINER, "Enabling rdebug-ide for Grizzly/Rails.");
rdebugScript = new File(rdebug);
if(rdebugScript.exists()) {
List args = new ArrayList();
// version is optional
String rdebugVersion = System.getProperty("glassfish.rdebug.version");
if(rdebugVersion != null && rdebugVersion.length() > 0) {
args.add(rdebugVersion);
}
// port spec is required
String debugPort = System.getProperty("glassfish.rdebug.port");
if(debugPort != null && debugPort.length() > 0) {
args.add("-l");
args.add("-p");
args.add(debugPort);
if("true".equals(System.getProperty("glassfish.rdebug.verbose"))) {
args.add("-d");
}
args.add("--");
File script = null;
Writer writer = null;
try {
script = File.createTempFile("grizzly_jruby_debug_", ".rb");
script.deleteOnExit();
writer = new FileWriter(script);
writer.write(
"#!/usr/bin/env jruby\n" +
"#\n" +
"# Launch script for Grizzly/JRuby connector when debugging Rails apps\n" +
"# on GlassFish V3.\n" +
"#\n" +
"require \"" + railsRoot.replace("\\", "/") + "/config/environment\"\n" +
"require \"cgi/force_nph\"\n" +
"require \"dispatcher\"\n"
);
writer.flush();
args.add(script.getAbsolutePath());
config.setArgv(args.toArray(new String [args.size()]));
} catch(IOException ex) {
SelectorThread.logger().log(Level.SEVERE,
"Error writing Rails launch script for rdebug.", ex);
rdebugScript = null;
} finally {
if(writer != null) {
try {
writer.close();
} catch(IOException ex) {
SelectorThread.logger().log(Level.SEVERE,
"Exception closing " + script.getAbsolutePath(), ex);
}
}
}
} else {
SelectorThread.logger().log(Level.SEVERE,
"glassfish.rdebug.port undefined. Disabling rdebug.");
rdebugScript = null;
}
} else {
SelectorThread.logger().log(Level.SEVERE,
"rdebug-ide script " + rdebugScript.getAbsolutePath() +
" does not exist. Disabling rdebug");
rdebugScript = null;
}
}
return rdebugScript;
}
public String getJrubyLib() {
return jrubyLib;
}
private String getDispatcherString() {
String str;
StringBuffer completeText = new StringBuffer();
try {
InputStream is = getClass().getResourceAsStream("/dispatch.rb");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
str = br.readLine();
while (str != null) {
completeText.append(str);
completeText.append("\n");
str = br.readLine();
}
} catch (Exception e) {
SelectorThread.logger().log(Level.WARNING, Messages.format(Messages.DISPATCH_STR_ERROR), e);
}
return completeText.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy