3

Okay, so I created a JavaScript file called test.js which contains the following code:

print("It works!");

I compiled it using the Rhino JavaScript Compiler without any errors. Then I created a new file called foo.js which contains this code:

var test = require("./test.class");

Now when I run foo.js in Ringo in throws the following exception and stack trace:

Uncaught exception:
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.ringojs.tools.launcher.Main.run(Main.java:66)
    at org.ringojs.tools.launcher.Main.main(Main.java:45)
Caused by: java.lang.NoClassDefFoundError: /home/aaditmshah/test (wrong name: test)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
    at org.mozilla.javascript.DefiningClassLoader.defineClass(DefiningClassLoader.java:62)
    at org.ringojs.engine.ClassModuleLoader.load(ModuleLoader.java:126)
    at org.ringojs.engine.ReloadableScript.compileScript(ReloadableScript.java:153)
    at org.ringojs.engine.ReloadableScript.getScript(ReloadableScript.java:118)
    at org.ringojs.engine.ReloadableScript.exec(ReloadableScript.java:227)
    at org.ringojs.engine.ReloadableScript.load(ReloadableScript.java:215)
    at org.ringojs.engine.RingoWorker.loadModuleInternal(RingoWorker.java:283)
    at org.ringojs.engine.Require.call(Require.java:81)
    at org.mozilla.javascript.optimizer.OptRuntime.callName(OptRuntime.java:97)
    at org.mozilla.javascript.gen._home_aaditmshah_foo_js_3._c_script_0(/home/aaditmshah/foo.js:1)
    at org.mozilla.javascript.gen._home_aaditmshah_foo_js_3.call(/home/aaditmshah/foo.js)
    at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:426)
    at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3178)
    at org.mozilla.javascript.gen._home_aaditmshah_foo_js_3.call(/home/aaditmshah/foo.js)
    at org.mozilla.javascript.gen._home_aaditmshah_foo_js_3.exec(/home/aaditmshah/foo.js)
    at org.ringojs.engine.ReloadableScript.evaluate(ReloadableScript.java:186)
    at org.ringojs.engine.RingoWorker.evaluateScript(RingoWorker.java:315)
    at org.ringojs.engine.RhinoEngine.runScript(RhinoEngine.java:186)
    at org.ringojs.tools.RingoRunner.run(RingoRunner.java:152)
    ... 6 more
enter code here

I don't know where am I going wrong. I have the latest versions of Ringo and Rhino 1.7R3. I added the current directory to my classpath by prepending the following line to foo.js:

addToClasspath(module.resolve("."));

However, it still generates the same error. I have no idea how to make this work. Any help will be greatly appreciated.

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299

1 Answers1

2

OK, I looked at the stack trace a little closer, and realized it's finding the class file correctly, it just tries to load it from the wrong package (home.aaditmshah.test instead of just test). If the class file is in your module path, you can load it correctly with just the module (class) name. By default, the current directory isn't in the module path, so you'll have to add it first:

require.paths.push('.')
var test = require("test.class");
Matthew Crumley
  • 101,441
  • 24
  • 103
  • 129
  • Actually the `.class` extension is necessary since it tells the `ModuleLoader` that the file being required is JavaScript compiled by the Rhino `jsc` tool. If you drop the `.class` extension it will try to load the `.js` file of the same name. See the following commit: https://github.com/ringo/ringojs/commit/20eee6739da7c69bf93c19d544abc2896df6b7a5 – Aadit M Shah Mar 15 '12 at 14:14
  • @AaditMShah I looked at the error message closer and updated my answer. I don't know if you get notified of edits, so here you go. – Matthew Crumley Mar 15 '12 at 18:06
  • Thank you. That solved my problem. Thank you for taking your time to make me understand my mistake. Really appreciated. =) – Aadit M Shah Mar 15 '12 at 18:10
  • Thanks for bringing this issue up! Yes, in order to load a Java class, Ringo has to know its complete class name (including package name). We could probably extract this from the class file, but currently the name is derived from the ringo module name. And in the case of a module loaded from outside the module search path, that is the full file path. Maybe this is something we can improve. – Hannes Wallnöfer Mar 15 '12 at 19:59
  • @HannesWallnöfer If you want to keep the restriction that the package name is based on the module path, maybe you could make sure that the package name matches the end of the path name. So `/path/to/org/package/classname` would work for the class `org.package.classname` (or just `classname`, etc.), but not `org.somethingElse.classname`. Just a thought. – Matthew Crumley Mar 15 '12 at 20:27