org.jruby.runtime.load
Class LoadService

java.lang.Object
  extended by org.jruby.runtime.load.LoadService
Direct Known Subclasses:
TestRubyInstanceConfig.NullLoadService

public class LoadService
extends java.lang.Object

How require works in JRuby When requiring a name from Ruby, JRuby will first remove any file extension it knows about, thereby making it possible to use this string to see if JRuby has already loaded the name in question. If a .rb extension is specified, JRuby will only try those extensions when searching. If a .so, .o, .dll, or .jar extension is specified, JRuby will only try .so or .jar when searching. Otherwise, JRuby goes through the known suffixes (.rb, .rb.ast.ser, .so, and .jar) and tries to find a library with this name. The process for finding a library follows this order for all searchable extensions:

  1. First, check if the name starts with 'jar:', then the path points to a jar-file resource which is returned.
  2. Second, try searching for the file in the current dir
  3. Then JRuby looks through the load path trying these variants:
    1. See if the current load path entry starts with 'jar:', if so check if this jar-file contains the name
    2. Otherwise JRuby tries to construct a path by combining the entry and the current working directy, and then see if a file with the correct name can be reached from this point.
  4. If all these fail, try to load the name as a resource from classloader resources, using the bare name as well as the load path entries
  5. When we get to this state, the normal JRuby loading has failed. At this stage JRuby tries to load Java native extensions, by following this process:
    1. First it checks that we haven't already found a library. If we found a library of type JarredScript, the method continues.
    2. The first step is translating the name given into a valid Java Extension class name. First it splits the string into each path segment, and then makes all but the last downcased. After this it takes the last entry, removes all underscores and capitalizes each part separated by underscores. It then joins everything together and tacks on a 'Service' at the end. Lastly, it removes all leading dots, to make it a valid Java FWCN.
    3. If the previous library was of type JarredScript, we try to add the jar-file to the classpath
    4. Now JRuby tries to instantiate the class with the name constructed. If this works, we return a ClassExtensionLibrary. Otherwise, the old library is put back in place, if there was one.
  6. When all separate methods have been tried and there was no result, a LoadError will be raised.
  7. Otherwise, the name will be added to the loaded features, and the library loaded
How to make a class that can get required by JRuby

First, decide on what name should be used to require the extension. In this purely hypothetical example, this name will be 'active_record/connection_adapters/jdbc_adapter'. Then create the class name for this require-name, by looking at the guidelines above. Our class should be named active_record.connection_adapters.JdbcAdapterService, and implement one of the library-interfaces. The easiest one is BasicLibraryService, where you define the basicLoad-method, which will get called when your library should be loaded.

The next step is to either put your compiled class on JRuby's classpath, or package the class/es inside a jar-file. To package into a jar-file, we first create the file, then rename it to jdbc_adapter.jar. Then we put this jar-file in the directory active_record/connection_adapters somewhere in JRuby's load path. For example, copying jdbc_adapter.jar into JRUBY_HOME/lib/ruby/site_ruby/1.8/active_record/connection_adapters will make everything work. If you've packaged your extension inside a RubyGem, write a setub.rb-script that copies the jar-file to this place.

If you don't want to have the name of your extension-class to be prescribed, you can also put a file called jruby-ext.properties in your jar-files META-INF directory, where you can use the key .impl to make the extension library load the correct class. An example for the above would have a jruby-ext.properties that contained a ruby like: "active_record/connection_adapters/jdbc_adapter=org.jruby.ar.JdbcAdapter". (NOTE: THIS FEATURE IS NOT IMPLEMENTED YET.)

Author:
jpetersen

Nested Class Summary
 class LoadService.AlreadyLoaded
           
 class LoadService.BailoutSearcher
           
 class LoadService.ClassLoaderSearcher
           
 class LoadService.ExtensionSearcher
           
static interface LoadService.LoadSearcher
           
 class LoadService.NormalSearcher
           
 class LoadService.ScriptClassSearcher
           
 class LoadService.SearchState
           
 
Field Summary
protected  java.util.Map<java.lang.String,IAutoloadMethod> autoloadMap
           
protected  java.util.Map<java.lang.String,Library> builtinLibraries
           
protected static java.util.regex.Pattern extensionPattern
           
protected  java.util.Map<java.lang.String,java.util.jar.JarFile> jarFiles
           
protected  RubyArray loadedFeatures
           
protected  java.util.List loadedFeaturesInternal
           
protected  RubyArray loadPath
           
protected  Ruby runtime
           
protected static java.util.regex.Pattern sourcePattern
           
 
Constructor Summary
LoadService(Ruby runtime)
           
 
Method Summary
 void addAutoload(java.lang.String name, IAutoloadMethod loadMethod)
           
 void addBuiltinLibrary(java.lang.String name, Library library)
           
 IRubyObject autoload(java.lang.String name)
           
 IAutoloadMethod autoloadFor(java.lang.String name)
           
 LoadService.SearchState findFileForLoad(java.lang.String file)
           
 IRubyObject getLoadedFeatures()
           
 IRubyObject getLoadPath()
           
 void init(java.util.List additionalDirectories)
           
 void load(java.lang.String file, boolean wrap)
           
 boolean lockAndRequire(java.lang.String requireName)
           
 void removeAutoLoadFor(java.lang.String name)
           
 void removeBuiltinLibrary(java.lang.String name)
           
 void removeInternalLoadedFeature(java.lang.String name)
           
 boolean require(java.lang.String file)
           
 boolean smartLoad(java.lang.String file)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

sourcePattern

protected static final java.util.regex.Pattern sourcePattern

extensionPattern

protected static final java.util.regex.Pattern extensionPattern

loadPath

protected RubyArray loadPath

loadedFeatures

protected RubyArray loadedFeatures

loadedFeaturesInternal

protected java.util.List loadedFeaturesInternal

builtinLibraries

protected final java.util.Map<java.lang.String,Library> builtinLibraries

jarFiles

protected final java.util.Map<java.lang.String,java.util.jar.JarFile> jarFiles

autoloadMap

protected final java.util.Map<java.lang.String,IAutoloadMethod> autoloadMap

runtime

protected final Ruby runtime
Constructor Detail

LoadService

public LoadService(Ruby runtime)
Method Detail

init

public void init(java.util.List additionalDirectories)

load

public void load(java.lang.String file,
                 boolean wrap)

findFileForLoad

public LoadService.SearchState findFileForLoad(java.lang.String file)
                                        throws LoadService.AlreadyLoaded
Throws:
LoadService.AlreadyLoaded

lockAndRequire

public boolean lockAndRequire(java.lang.String requireName)

smartLoad

public boolean smartLoad(java.lang.String file)

require

public boolean require(java.lang.String file)

getLoadPath

public IRubyObject getLoadPath()

getLoadedFeatures

public IRubyObject getLoadedFeatures()

autoloadFor

public IAutoloadMethod autoloadFor(java.lang.String name)

removeAutoLoadFor

public void removeAutoLoadFor(java.lang.String name)

autoload

public IRubyObject autoload(java.lang.String name)

addAutoload

public void addAutoload(java.lang.String name,
                        IAutoloadMethod loadMethod)

addBuiltinLibrary

public void addBuiltinLibrary(java.lang.String name,
                              Library library)

removeBuiltinLibrary

public void removeBuiltinLibrary(java.lang.String name)

removeInternalLoadedFeature

public void removeInternalLoadedFeature(java.lang.String name)


Copyright © 2002-2007 JRuby Team. All Rights Reserved.