En la versión del código que estoy usando ahora, también hice que los módulos se carguen un toque distintos para que haya mejores stack-traces (ese cambio está en la función require). Bueno, abajo pongo el código:
/*
* Does not support relative paths (yet?).
* Can be invoked by several threads.
*
* Uses the classloader to fetch js modules.
*/
var require = function (id) {
try {
require.lock.lock() // Avoid threading issues while loading modules.
if (!require.modules[id]) {
var modCode = require.loadMod(id)
var exports = {}
require.modules[id] = exports
var module = {
id : id
}
var context = {
exports: exports,
module: module,
}
if(!modCode) {
throw new require.RequireError(id, "module not found")
}
org.mozilla.javascript.Context.getCurrentContext().evaluateString(
context,
modCode,
id,
1,
null
)
/*
Old style invocation, should work in the browser but has worst error messages.
var f = new Function("require", "exports", "module", modCode)
f.call(context, require, exports, module) */
}
return require.modules[id]
} catch (x) {
if (x instanceof require.RequireError) {
throw x
} else {
throw new require.RequireError(id, x)
}
} finally {
require.lock.unlock()
}
}
require.loaders = []
require.modules = {}
require.lock = new java.util.concurrent.locks.ReentrantLock()
var RequireErrorProto = {}
require.RequireError = function(moduleId, cause) {
this.moduleId = moduleId
this.cause = cause
}
require.RequireError.prototype = RequireErrorProto
require.RequireError.prototype.toString = function() {
return "Error loading " + this.moduleId + ( this.cause ? ". Cause: " + this.cause : "" )
}
require.RequireError.prototype.name = "RequireError"
require.load = function(path) {
return java.lang.Class.forName("java.lang.String").getResourceAsStream(path)
}
require.loadMod = function(id) {
function path(id) {
return "/" + id + ".js"
}
function readFromStream(stream) {
var io = java.io
var reader = new io.BufferedReader( new io.InputStreamReader(stream) )
try {
var stringBuffer = new java.lang.StringBuffer()
var line = ""
while( line = reader.readLine()) {
stringBuffer.append(line)
stringBuffer.append("\n")
}
return stringBuffer.toString()
} finally {
reader.close()
}
}
var stream = require.load(path(id))
if (!stream) { return null }
return readFromStream(stream)
}
/**
* Resets the module cache.
*
* It will reload all the modules. Old modules referenced will still be working.
*/
require.reset = function() {
try {
require.lock.lock()
require.modules = {}
} finally {
require.lock.unlock()
}
}
Este cambio también simplifico el RhinoServlet, y ahora toma sus scripts del classpath también.
Happy hacking,
Aureliano
No hay comentarios.:
Publicar un comentario