org.glassfish.scripting.rails.RailsApplication Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grizzly-jruby-module Show documentation
Show all versions of grizzly-jruby-module Show documentation
JRuby container and deployer for GlassFish v3
/*
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.scripting.rails;
import com.sun.grizzly.tcp.Request;
import com.sun.grizzly.tcp.Response;
import org.glassfish.api.container.Adapter;
import org.glassfish.api.deployment.ApplicationContainer;
import java.io.File;
import java.io.FilenameFilter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This is the main Rails application class. It is created from {@link RailsDeployer} during
* {@link org.glassfish.api.deployment.Deployer#load(org.glassfish.api.container.Container, org.glassfish.api.deployment.DeploymentContext)}.
*
* RailsApplication composes with {@link com.sun.grizzly.jruby.RailsAdapter}. RailsAdapter create and maintains the JRuby runtime and manages Ruby runtime pool.
* This basically means that each Rails application will have it's own JRuby runtime object pool. This was the only way to manage the
* JRuby runtime pool, ideally it could be per container but due to the fact that loading application specific Rails environment thru JRuby
* is quite expensive.
*
* @author vivek Pandey
*/
public class RailsApplication implements ApplicationContainer, Adapter {
private final Logger logger;
private Object jRubyRuntime;
private com.sun.grizzly.tcp.Adapter adapter;
private final String contextRoot;
private final RailsDeployer.JRubyEnvironment jrubyEnv;
RailsApplication(RailsDeployer.JRubyEnvironment env, String railsRoot, Logger logger, String ctxRoot){
this.logger = logger;
this.jrubyEnv = env;
this.contextRoot = ctxRoot;
try {
/**
* JRuby is not a OSGi bundle so it needs to be passed custom class loader that makes all the jruby jars availble and also
* can load any of the java classes available inside the context classloader.
*
* So we have a jruby runtime specific wrapper class that weload using custom classloader and this classloader will eventually
* be used to load everyting else by jruby.
*/
URL[] urls = findJRubyJars();
ClassLoader cl = new URLClassLoader(urls, RailsApplication.class.getClassLoader());
Class> c = cl.loadClass("com.sun.grizzly.jruby.RubyRuntime");
this.jRubyRuntime = c.getConstructor(String.class, String.class, String.class, int.class, int.class, int.class, boolean.class).newInstance(contextRoot, railsRoot, jrubyEnv.jrubyLib, jrubyEnv.numberOfRuntime, jrubyEnv.minRuntime, jrubyEnv.maxRuntime, true);
this.adapter = (com.sun.grizzly.tcp.Adapter) c.getMethod("getAdapter").invoke(jRubyRuntime);
} catch (Exception e) {
logger.log(Level.SEVERE, Messages.format(Messages.ERR_CREATING_RAILSADAPTOR, e.getMessage()), e);
return;
}
}
com.sun.grizzly.tcp.Adapter getAdapter() {
return adapter;
}
/**
* Stop the application container
* ContractProvider should manage the number of outstanding ContractProvider instances are
* started and free up resources when that number dip to zero.
*
* @return true if stopping was successful.
*/
public boolean stop(org.glassfish.api.deployment.ApplicationContext startupContext) {
try {
jRubyRuntime.getClass().getMethod("stopRubyRuntimePool").invoke(jRubyRuntime);
} catch (Exception e) {
logger.log(Level.WARNING, Messages.format(Messages.ERR_STOPPING_RAILSAPP, contextRoot, e.getMessage()), e);
}
return true;
}
/**
* Suspends this application container.
*
* @return true if suspending was successful, false otherwise.
*/
public boolean suspend() {
// Not (yet) supported
return false;
}
/**
* Resumes this application container.
*
* @return true if resumption was successful, false otherwise.
*/
public boolean resume() {
// Not (yet) supported
return false;
}
public ClassLoader getClassLoader() {
return null;
}
/**
* Returns the deployment descriptor associated with this application
*
* @return deployment descriptor if they exist or null if not
*/
public Object getDescriptor() {
return null;
}
public boolean start(org.glassfish.api.deployment.ApplicationContext startupContext) {
return true;
}
public String getContextRoot() {
return contextRoot;
}
public void service(Request request, Response response) throws Exception {
adapter.service(request, response);
}
public void afterService(Request request, Response response) throws Exception {
adapter.afterService(request, response);
}
private URL[] findJRubyJars() throws MalformedURLException, ClassNotFoundException {
List urls = new ArrayList();
File jrubyLibDir = new File(jrubyEnv.jrubyLib);
File jrubyJar = new File(jrubyEnv.jrubyLib, "jruby.jar");
if (!jrubyJar.exists()) {
throw new IllegalArgumentException(Messages.format(Messages.ERR_JRUBYLIB_NOTFOUND, jrubyEnv.jrubyLib));
}
for (File lib : jrubyLibDir.listFiles()) {
if (lib.isFile() && lib.toString().endsWith(".jar")) {
urls.add(lib.toURI().toURL());
}
}
//Add $GLASSFISH_HOME/modules
File grizzlyjruby = jrubyEnv.rootDir;
File[] grizzlyjrubyJars = grizzlyjruby.listFiles(new FilenameFilter(){
public boolean accept(File dir, String name) {
return !name.startsWith("grizzly-jruby-module") && name.startsWith("grizzly-jruby");
}
});
//TODO: if there are more than one, print warning and add the latest version
if(grizzlyjrubyJars.length > 0)
urls.add(grizzlyjrubyJars[0].toURI().toURL());
return urls.toArray(new URL[urls.size()]);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy