org.jruby.runtime.load
Class LoadService

java.lang.Object
  extended by org.jruby.runtime.load.LoadService

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
           
static class LoadService.SuffixType
           
 
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  java.util.Map requireLocks
           
protected  Ruby runtime
           
protected  java.util.List<LoadService.LoadSearcher> searchers
           
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)
           
protected  void addLoadedFeature(RubyString loadNameRubyString)
           
protected  void addPath(java.lang.String path)
           
 IRubyObject autoload(java.lang.String name)
           
 IAutoloadMethod autoloadFor(java.lang.String name)
           
protected  java.lang.String buildClassName(java.lang.String className)
           
protected  java.lang.String canonicalizePath(java.lang.String path)
           
protected  void checkEmptyLoad(java.lang.String file)
           
protected  Library createLibrary(LoadService.SearchState state, LoadServiceResource resource)
           
protected  void debugLogFound(LoadServiceResource resource)
           
protected  void debugLogFound(java.lang.String what, java.lang.String msg)
           
protected  void debugLogTry(java.lang.String what, java.lang.String msg)
           
protected  boolean featureAlreadyLoaded(RubyString loadNameRubyString)
           
protected  Library findBuiltinLibrary(LoadService.SearchState state, java.lang.String baseName, LoadService.SuffixType suffixType)
           
 LoadService.SearchState findFileForLoad(java.lang.String file)
           
protected  LoadServiceResource findFileInClasspath(java.lang.String name)
          this method uses the appropriate lookup strategy to find a file.
protected  Library findLibraryWithClassloaders(LoadService.SearchState state, java.lang.String baseName, LoadService.SuffixType suffixType)
           
protected  Library findLibraryWithoutCWD(LoadService.SearchState state, java.lang.String baseName, LoadService.SuffixType suffixType)
           
 IRubyObject getLoadedFeatures()
           
 IRubyObject getLoadPath()
           
 void init(java.util.List additionalDirectories)
           
protected  boolean isJarfileLibrary(LoadService.SearchState state, java.lang.String file)
           
protected  boolean isRequireable(java.net.URL loc)
           
 void load(java.lang.String file, boolean wrap)
           
protected  boolean loadPathLooksLikeJarURL(java.lang.String loadPathEntry)
           
 boolean lockAndRequire(java.lang.String requireName)
           
static void reflectedLoad(Ruby runtime, java.lang.String libraryName, java.lang.String className, java.lang.ClassLoader classLoader, boolean wrap)
          Load the org.jruby.runtime.load.Library implementation specified by className.
 void removeAutoLoadFor(java.lang.String name)
           
 void removeBuiltinLibrary(java.lang.String name)
           
 void removeInternalLoadedFeature(java.lang.String name)
           
protected  void removeLoadedFeature(RubyString loadNameRubyString)
           
 boolean require(java.lang.String file)
           
protected  void reraiseRaiseExceptions(java.lang.Throwable e)
           
 boolean smartLoad(java.lang.String file)
           
protected  boolean tryLoadingLibraryOrScript(Ruby runtime, LoadService.SearchState state)
           
protected  LoadServiceResource tryResourceAsIs(java.lang.String namePlusSuffix)
           
protected  LoadServiceResource tryResourceFromCWD(LoadService.SearchState state, java.lang.String baseName, LoadService.SuffixType suffixType)
           
protected  LoadServiceResource tryResourceFromJarURL(LoadService.SearchState state, java.lang.String baseName, LoadService.SuffixType suffixType)
           
protected  LoadServiceResource tryResourceFromJarURLWithLoadPath(java.lang.String namePlusSuffix, java.lang.String loadPathEntry)
           
protected  LoadServiceResource tryResourceFromLoadPath(java.lang.String namePlusSuffix, java.lang.String loadPathEntry)
           
protected  LoadServiceResource tryResourceFromLoadPathOrURL(LoadService.SearchState state, java.lang.String baseName, LoadService.SuffixType suffixType)
           
 
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

requireLocks

protected java.util.Map requireLocks

searchers

protected final java.util.List<LoadService.LoadSearcher> searchers
Constructor Detail

LoadService

public LoadService(Ruby runtime)
Method Detail

init

public void init(java.util.List additionalDirectories)

addLoadedFeature

protected void addLoadedFeature(RubyString loadNameRubyString)

addPath

protected void addPath(java.lang.String path)

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)

reflectedLoad

public static void reflectedLoad(Ruby runtime,
                                 java.lang.String libraryName,
                                 java.lang.String className,
                                 java.lang.ClassLoader classLoader,
                                 boolean wrap)
Load the org.jruby.runtime.load.Library implementation specified by className. The purpose of using this method is to avoid having static references to the given library class, thereby avoiding the additional classloading when the library is not in use.

Parameters:
runtime - The runtime in which to load
libraryName - The name of the library, to use for error messages
className - The class of the library
classLoader - The classloader to use to load it
wrap - Whether to wrap top-level in an anonymous module

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)

featureAlreadyLoaded

protected boolean featureAlreadyLoaded(RubyString loadNameRubyString)

isJarfileLibrary

protected boolean isJarfileLibrary(LoadService.SearchState state,
                                   java.lang.String file)

removeLoadedFeature

protected void removeLoadedFeature(RubyString loadNameRubyString)

reraiseRaiseExceptions

protected void reraiseRaiseExceptions(java.lang.Throwable e)
                               throws RaiseException
Throws:
RaiseException

tryLoadingLibraryOrScript

protected boolean tryLoadingLibraryOrScript(Ruby runtime,
                                            LoadService.SearchState state)

buildClassName

protected java.lang.String buildClassName(java.lang.String className)

checkEmptyLoad

protected void checkEmptyLoad(java.lang.String file)
                       throws RaiseException
Throws:
RaiseException

debugLogTry

protected void debugLogTry(java.lang.String what,
                           java.lang.String msg)

debugLogFound

protected void debugLogFound(java.lang.String what,
                             java.lang.String msg)

debugLogFound

protected void debugLogFound(LoadServiceResource resource)

findBuiltinLibrary

protected Library findBuiltinLibrary(LoadService.SearchState state,
                                     java.lang.String baseName,
                                     LoadService.SuffixType suffixType)

findLibraryWithoutCWD

protected Library findLibraryWithoutCWD(LoadService.SearchState state,
                                        java.lang.String baseName,
                                        LoadService.SuffixType suffixType)

findLibraryWithClassloaders

protected Library findLibraryWithClassloaders(LoadService.SearchState state,
                                              java.lang.String baseName,
                                              LoadService.SuffixType suffixType)

createLibrary

protected Library createLibrary(LoadService.SearchState state,
                                LoadServiceResource resource)

tryResourceFromCWD

protected LoadServiceResource tryResourceFromCWD(LoadService.SearchState state,
                                                 java.lang.String baseName,
                                                 LoadService.SuffixType suffixType)
                                          throws RaiseException
Throws:
RaiseException

tryResourceFromJarURL

protected LoadServiceResource tryResourceFromJarURL(LoadService.SearchState state,
                                                    java.lang.String baseName,
                                                    LoadService.SuffixType suffixType)

tryResourceFromLoadPathOrURL

protected LoadServiceResource tryResourceFromLoadPathOrURL(LoadService.SearchState state,
                                                           java.lang.String baseName,
                                                           LoadService.SuffixType suffixType)

tryResourceFromJarURLWithLoadPath

protected LoadServiceResource tryResourceFromJarURLWithLoadPath(java.lang.String namePlusSuffix,
                                                                java.lang.String loadPathEntry)

loadPathLooksLikeJarURL

protected boolean loadPathLooksLikeJarURL(java.lang.String loadPathEntry)

tryResourceFromLoadPath

protected LoadServiceResource tryResourceFromLoadPath(java.lang.String namePlusSuffix,
                                                      java.lang.String loadPathEntry)
                                               throws RaiseException
Throws:
RaiseException

tryResourceAsIs

protected LoadServiceResource tryResourceAsIs(java.lang.String namePlusSuffix)
                                       throws RaiseException
Throws:
RaiseException

findFileInClasspath

protected LoadServiceResource findFileInClasspath(java.lang.String name)
this method uses the appropriate lookup strategy to find a file. It is used by Kernel#require.

Parameters:
name - the file to find, this is a path name
Returns:
the correct file

isRequireable

protected boolean isRequireable(java.net.URL loc)

canonicalizePath

protected java.lang.String canonicalizePath(java.lang.String path)


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