4

Alright, so I created a JavaScript file named HelloWorld.js with the following contents:

java.lang.System.out.println("Hello World!");

Now, I compiled it using the Rhino JavaScript Compiler using the following command (the js.jar file is in my classpath):

java org.mozilla.javascript.tools.jsc.Main HelloWorld.js

It compiled the JavaScript file and created the Java class file as expected. Then I tried to execute the Java class file by calling java HelloWorld. However, it generated the following error message:

Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld
Caused by: java.lang.ClassNotFoundException: HelloWorld
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Could not find the main class: HelloWorld. Program will exit.

I tried to understand what caused the java.lang.NoClassDefFoundError to be thrown, and from what I read in this blog post I learned that the java.lang.NoClassDefFoundError is thrown if a class was present during compile time but not available in Java classpath during runtime.

So I ran the javap HelloWorld command to check what the problem is, and this is what I got:

public class HelloWorld extends org.mozilla.javascript.NativeFunction implements org.mozilla.javascript.Script {
    public HelloWorld();
    public static void main(java.lang.String[]);
    public final java.lang.Object exec(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable);
    public final java.lang.Object call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[]);
    public int getLanguageVersion();
    public java.lang.String getFunctionName();
    public int getParamCount();
    public int getParamAndVarCount();
    public java.lang.String getParamOrVarName(int);
    public boolean getParamOrVarConst(int);
}

Now, what I understand from this is that the HelloWorld class is present and is declared as public. Hence there shouldn't be any reason why the Java Virtual Machine can't find it. This is where I'm confused. I don't know where to go from here, nor what to do to resolve this problem.

I found out that I could execute the Java class file if I invoked Rhino to call the exec method on an instance of HelloWorld as follows:

java -jar /usr/share/rhino/js.jar HelloWorld.class

However, I would like to execute the Java class file using the java HelloWorld command directly since the js.jar file already in my classpath. I would like to understand what the problem is so that I know what's really happening behind the scenes.

8
  • 1
    JavaScript file named HelloWorld.java o_O. Rhino executes js (javascript) files, not Java ones. In order to run Java programs, one doesn't need to have Rhino. Commented Mar 11, 2012 at 8:34
  • @kirilloid: In order to run Java classes compiled by Rhino, one needs the Rhino runtime library. Commented Mar 11, 2012 at 8:37
  • @Thilo Does Rhino compile js to Java? Commented Mar 11, 2012 at 8:40
  • It can compile to Java class files, yes. Note that the OP successfully created a HelloWorld.class that javap can read. Commented Mar 11, 2012 at 8:41
  • Then don't listen to me =) I thought, Rhino could only execute js files. Commented Mar 11, 2012 at 8:51

1 Answer 1

3

Are you sure the class file is on the classpath (as well as js.jar)?

Try

java -cp .;js.jar HelloWorld

(assuming HelloWorld.class in the current directory, otherwise something like -cp build;js.jar).

Sign up to request clarification or add additional context in comments.

3 Comments

I found out what the problem was. My HelloWorld class wasn't in the classpath. So I updated the following line in my .bashrc to reflect the change export CLASSPATH=/usr/share/rhino/js.jar:$HOME/class. Then I moved my HelloWorld.class file to $HOME/class. That solved the problem. When I executed java HelloWorld from the class directory it showed me the output without any errors. Thank you for your help. I just have one more question: why couldn't the Java Virtual Machine find my HelloWorld.class file when I was explicitly trying to execute it? I don't understand what happened.
The current directory is not necessarily in the classpath. I think, when you have other things set there, it will not be added unless you explicitly put it in. Try to avoid environment variables, and use -cp or runnable jar files or an IDE. Environment tends to leak into applications that don't need it and mess them up.
Makes sense. I'll continue using environment variables for development purposes. The good thing about .bashrc is that it only modifies the current user's environment variables. For production code I'll create a shell script which uses the -classpath option to explicitly set the classpath. =)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.