org.jruby.runtime.load
Class LoadService
java.lang.Object
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:
- First, check if the name starts with 'jar:', then the path points to a jar-file resource which is returned.
- Second, try searching for the file in the current dir
- Then JRuby looks through the load path trying these variants:
- See if the current load path entry starts with 'jar:', if so check if this jar-file contains the name
- 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.
- 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
- 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:
- First it checks that we haven't already found a library. If we found a library of type JarredScript, the method continues.
- 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.
- If the previous library was of type JarredScript, we try to add the jar-file to the classpath
- 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.
- When all separate methods have been tried and there was no result, a LoadError will be raised.
- 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
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 |
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
LoadService
public LoadService(Ruby runtime)
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 loadlibraryName
- The name of the library, to use for error messagesclassName
- The class of the libraryclassLoader
- The classloader to use to load itwrap
- 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.