Class LoadService

java.lang.Object
org.jruby.runtime.load.LoadService
Direct Known Subclasses:
OSGiLoadService

public class LoadService extends 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
Author:
jpetersen
  • Field Details

    • sourcePattern

      protected static final Pattern sourcePattern
    • extensionPattern

      protected static final Pattern extensionPattern
    • loadPath

      protected RubyArray loadPath
    • loadedFeatures

      protected StringArraySet loadedFeatures
    • jarFiles

      protected final Map<String,JarFile> jarFiles
    • runtime

      protected final Ruby runtime
    • librarySearcher

      protected LibrarySearcher librarySearcher
    • mainScript

      protected String mainScript
    • mainScriptPath

      protected String mainScriptPath
  • Constructor Details

    • LoadService

      public LoadService(Ruby runtime)
  • Method Details

    • init

      public void init(List<String> prependDirectories)
      Called to initialize the load path with a set of optional prepended directories and then the standard set of dirs. This should only be called once, at load time, since it wipes out loaded features.
      Parameters:
      prependDirectories -
    • addPaths

      public void addPaths(List<String> additionalDirectories)
      Add additional directories to the load path.
      Parameters:
      additionalDirectories - a List of additional dirs to append to the load path
    • addPaths

      public void addPaths(String... additionalDirectories)
      Add additional directories to the load path.
      Parameters:
      additionalDirectories - an array of additional dirs to append to the load path
    • provide

      public void provide(String name)
    • addPath

      protected void addPath(String path)
    • getWrapperSelf

      public RubyModule getWrapperSelf()
    • load

      public void load(String file, IRubyObject wrapWith)
    • load

      public void load(String file, boolean wrap)
    • loadFromClassLoader

      public void loadFromClassLoader(ClassLoader classLoader, String file, boolean wrap)
    • require

      public boolean require(String requireName)
    • autoloadRequire

      public boolean autoloadRequire(RubyString requireName)
    • warnCircularRequire

      protected void warnCircularRequire(String requireName)
    • reflectedLoad

      public static void reflectedLoad(Ruby runtime, String libraryName, String className, 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()
    • isJarfileLibrary

      protected boolean isJarfileLibrary(Library library, String file)
    • tryLoadingLibraryOrScript

      protected boolean tryLoadingLibraryOrScript(Ruby runtime, Library library, String searchFile)
    • checkEmptyLoad

      protected void checkEmptyLoad(String file) throws RaiseException
      Throws:
      RaiseException
    • debugLogTry

      protected final void debugLogTry(String what, String msg)
    • debugLogFound

      protected final void debugLogFound(LoadServiceResource resource)
    • debugLogFound

      protected final void debugLogFound(String what, String msg)
    • searchForRequire

      public char searchForRequire(String file, LibrarySearcher.FoundLibrary[] path)
      Replaces findLibraryBySearchState but split off for require. Needed for OSGiLoadService to override.
    • searchForLoad

      protected LibrarySearcher.FoundLibrary searchForLoad(String file)
      Replaces findLibraryBySearchState but split off for load. Needed for OSGiLoadService to override.
    • featureAlreadyLoaded

      public boolean featureAlreadyLoaded(String feature)
    • featureAlreadyLoaded

      public boolean featureAlreadyLoaded(String feature, String[] loading)
    • findLibraryWithClassloaders

      protected LibrarySearcher.FoundLibrary findLibraryWithClassloaders(String baseName, LoadService.SuffixType suffixType)
    • createLibrary

      protected Library createLibrary(String baseName, String loadName, LoadServiceResource resource)
    • getLoadPathEntry

      protected String getLoadPathEntry(IRubyObject entry)
    • findFileInClasspath

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

      MRI: rb_find_file

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

      protected static boolean isRequireable(URL loc)
    • getClassPathResource

      public LoadServiceResource getClassPathResource(ClassLoader classLoader, String name)
    • classpathFilenameFromURL

      public static String classpathFilenameFromURL(String name, URL loc, boolean isClasspathScheme)
      Given a URL to a classloader resource, build an appropriate load string.
      Parameters:
      name - the original filename requested
      loc - the URL to the resource
      isClasspathScheme - whether we're using the classpath: sceheme
      Returns:
    • resolveLoadName

      protected String resolveLoadName(LoadServiceResource foundResource, String previousPath)
    • getMainScript

      public String getMainScript()
    • getMainScriptPath

      public String getMainScriptPath()
    • setMainScript

      public void setMainScript(String filename, String cwd)
    • getPathForLocation

      public String getPathForLocation(String filename)
    • tearDown

      public void tearDown()