| Class | Ruva::VM::ClassLoader |
| In: |
lib/ruva/class_loader.rb
|
| Parent: | Object |
Provides the top=level class-loading functionality for the VM. Instances of this class are usually created only at VM startup, and when a new java.lang.ClassLoader (or subclass) instance is created inside.
At runtime, the VM maintains a list of available ClassLoaders. New classloaders created outside Java code must be registered with the VM in order to be used by the system.
| parent | [RW] | |
| paths | [RW] |
# File lib/ruva/class_loader.rb, line 24
24: def initialize(parent, *paths)
25: @parent, @paths = parent, paths.map { |p| File.expand_path(p) }
26: end
define a class from the supplied byte array, optionally using a different name. The class is expected to begin with the class format signature at the specified start offset.
If a name is supplied, it must be in internal format, e.g. com/mycompany/ClassName.
TODO name change is not yet implemented. Should be just a case of swapping out the pool entry before resolving the class…
Returns the newly-created Class object.
# File lib/ruva/class_loader.rb, line 38
38: def define_class(bytes, class_name = nil, start_ofs = 0)
39: uclz = Class::Reader.bytes(bytes)
40:
41: if class_name
42: raise IllegalArgumentError, "Illegal class name #{class_name}" unless class_name =~ /[a-z0-9\/_]+/
43:
44: # ... here
45: end
46:
47: uclz.accept(Class.new)
48: end
Attempt to load a class by name. The supplied class name must be in internal format as described in define_class.
This will first delegate the search to the parent classloader, if any. If this search fails, the loader‘s paths are searched in order for a matching class.
The mod argument is the module into which any implicit natives should be loaded. If you know there aren‘t any, you can pass nil.
Returns the newly-created Class object, or nil if no matching class was found.
# File lib/ruva/class_loader.rb, line 61
61: def load_class(class_name, mod)
62: if class_name
63: # XXX delegation is done in Java by Classpath
64: #
65: #if parent && clz = parent.load_class(class_name)
66: # clz
67: #else
68: if fn = find_resource(class_name + '.class')
69: clz = define_class(File.read(fn))
70:
71: # Just try to load any native lib with the same name. If it
72: # is there, it'll be registered.
73: load_class_library(class_name, clz, mod)
74:
75: clz
76: end
77: #end
78: end
79: end
Load a native library that‘s implicitly associated with the class it implements natives for. This is used to load same-named ruby libs from alongside classes in the classpath.
The specified name should simply be the binary name of the class, which will be made into a filename automagically.
The mod is the module into which the natives should be loaded.
# File lib/ruva/class_loader.rb, line 110
110: def load_class_library(name, clz, mod)
111: fn = find_resource(name + '.rb')
112:
113: if fn && load_library(fn, mod)
114: # prelink the natives
115: mod = name.split('/').inject(mod) do |m, name|
116: name[0] = name[0,1].upcase unless name[0,1] =~ /[A-Z]/
117: m.const_get(name) || break
118: end
119:
120: !!clz.natives = mod
121: else
122: false
123: end
124: end
Attempt to load a ‘native’ library by name. In Ruva, ‘native’ means ‘ruby’. This method is used by the VMRuntime.nativeLoad java method to load libraries requested via System.loadLibrary. Currently, it expects classpath management to happen back in Java (it‘s how Classpath works) and so doesn‘t do any kind of processing on the name - it expects it‘s already a full path.
Note : You shouldn‘t generally call this directly - call vm.load_library instead to go through the class pool. Otherwise, you‘ll have to register everything yourself.
# File lib/ruva/class_loader.rb, line 92
92: def load_library(fn, mod)
93: if File.exist?(fn)
94: mod.module_eval(File.read(fn), fn)
95: true
96: else
97: false
98: end
99: end
Load a named resource from the classpath.
# File lib/ruva/class_loader.rb, line 129
129: def load_resource(name)
130: if fn = find_resource(name)
131: File.read(fn)
132: end
133: end