13 Replies Latest reply: Oct 30, 2009 12:21 PM by jschellSomeoneStoleMyAlias RSS

    Java -> JavaScript, static methods

    807580
      Hi,

      How do I call a static method of a class in JavaScript with the ScriptEngine?

      EG:
      package org.petah.common.test;
      
      import javax.script.ScriptEngine;
      import javax.script.ScriptEngineManager;
      
      public class StaticScriptTest {
      
          public static void main(String[] args) throws Exception {
              new StaticScriptTest();
          }
      
          public StaticScriptTest() throws Exception {
              // Create a script engine manager
              ScriptEngineManager factory = new ScriptEngineManager();
              // Create a JavaScript engine
              ScriptEngine engine = factory.getEngineByName("JavaScript");
      
              // Works
              engine.put("instance", this);
              engine.eval("instance.someMethod();");
      
              // Doesnt work
              engine.eval("SomeStaticClass.someStaticMethod();");
          }
      
          public void someMethod() {
              System.out.println("called: StaticScriptTest.someMethod()");
          }
      }
      package org.petah.common.test;
      
      public class SomeStaticClass {
      
          public static void someStaticMethod() {
              System.out.println("called: SomeStaticClass.someStaticMethod()");
          }
      }
        • 1. Re: Java -> JavaScript, static methods
          807580
          Don't know Javascript, and don't know the Java bindings for Javascript, but 2 other things you should try:
          -Fully qualifying the class name of SomeStaticClass (i.e. "org.petah.common.test.SomeStaticClass.someStaticMethod()")
          -Not using any class name (just eval "someStaticMethod()").
          • 2. Re: Java -> JavaScript, static methods
            807580
            I tried a whole bunch of combos and nothing worked.

            Some things I tried:
                    // Also doesnt work
                    engine.eval("org.petah.common.test.SomeStaticClass.someStaticMethod();");
                    
                    // Also doesnt work
                    engine.eval("importPackage(org.petah.common.test);");
                    engine.eval("SomeStaticClass.someStaticMethod();");
                    
                    // Also doesnt work
                    engine.eval("importClass(org.petah.common.test.SomeStaticClass);");
                    engine.eval("someStaticMethod();");
            • 3. Re: Java -> JavaScript, static methods
              807580
              I suppose this does work:
                      engine.put("SomeStaticClass", new SomeStaticClass());
                      engine.eval("SomeStaticClass.someStaticMethod();");
              But it seems silly to have to create an instance of a class that only has static methods.
              • 4. Re: Java -> JavaScript, static methods
                baftos
                Try this:
                ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
                engine.eval("java.lang.System.out.println(123)");
                Somehow the static member out of the class java.lang.System is accessible.
                Not sure if this will help you. I don't know how and why your own static is not.

                Edit:
                I did not try, but look at this example [http://www.java2s.com/Code/Java/JDK-6/UsingJavaObjectsinJavaScript.htm].
                It first imports the javax.swing package explicitly (perhaps you need to do this), than calls a static method of JOptionPane.

                Edited by: baftos on Oct 27, 2009 1:07 PM
                • 5. Re: Java -> JavaScript, static methods
                  baftos
                  Here you go:
                  package whatever;
                  
                  import javax.script.*;
                  
                  public class Try {
                    public static void hello() {
                       System.out.println("hello");
                    }
                    
                    public static void main(String[] args) throws Exception {
                      ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
                      engine.eval("importPackage(Packages.whatever);Try.hello();"); 
                    }
                  }
                  Edited by: baftos on Oct 27, 2009 4:50 PM
                  • 6. Re: Java -> JavaScript, static methods
                    jschellSomeoneStoleMyAlias
                    baftos wrote:
                    Here you go:
                    Perhaps you can address the following one (simply because I am curious as to the assertion.)

                    [http://forums.sun.com/thread.jspa?threadID=5411064]
                    • 7. Re: Java -> JavaScript, static methods
                      baftos
                      No. I am puzzled just like you and him. I cannot see any good reason to do this 'by design'.
                      If it's accidental, the Rhino code might reveal something, but I don't feel like checking it.
                      • 8. Re: Java -> JavaScript, static methods
                        jschellSomeoneStoleMyAlias
                        baftos wrote:
                        No. I am puzzled just like you and him. I cannot see any good reason to do this 'by design'.
                        If it's accidental, the Rhino code might reveal something, but I don't feel like checking it.
                        So the assertion is correct that it works for com and not others?
                        • 9. Re: Java -> JavaScript, static methods
                          baftos
                          jschell wrote:
                          baftos wrote:
                          No. I am puzzled just like you and him. I cannot see any good reason to do this 'by design'.
                          If it's accidental, the Rhino code might reveal something, but I don't feel like checking it.
                          So the assertion is correct that it works for com and not others?
                          I did not try, so I don't really know. I just assumed he was right...
                          • 10. Re: Java -> JavaScript, static methods
                            jschellSomeoneStoleMyAlias
                            baftos wrote:
                            I did not try, so I don't really know. I just assumed he was right...
                            I tried. I couldn't get it to work. But I know zero about JavaScript.
                            • 11. Re: Java -> JavaScript, static methods
                              baftos
                              Ok, I tried it and he is right. I kind of shortened his code in order to show the problem.
                              public class Test {
                                public static void main(String[] pArgs) throws Exception {
                                  javax.script.ScriptEngine engine = new javax.script.ScriptEngineManager().getEngineByName("JavaScript");
                              
                                  engine.eval("com.Test.m()");            // No problem
                                  engine.eval("Packages.xom.Test.m()");   // No problem
                                  engine.eval("xom.Test.m()");            // "xom" is not defined ScriptException !!!
                                }
                              }
                              (his com.Test and xom.Test classes are unchanged)

                              The com package seems to have a special status not enjoyed by the xom package, which absolutely needs the "Packages." prefix to be used.
                              • 12. Re: Java -> JavaScript, static methods
                                807580
                                According to [Importing Java Packages, Classes|http://java.sun.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html#jsimport] in the Java Scripting Programmer's Guide":

                                The Packages global variable can be used to access Java packages. Examples: Packages.java.util.Vector, Packages.javax.swing.JFrame. Please note that "java" is a shortcut for "Packages.java". There are equivalent shortcuts for javax, org, edu, com, net prefixes, so pratically all JDK platform classes can be accessed without the "Packages" prefix.

                                Note that java.lang is not imported by default (unlike Java) because that would result in conflicts with JavaScript's built-in Object, Boolean, Math and so on.
                                • 13. Re: Java -> JavaScript, static methods
                                  jschellSomeoneStoleMyAlias
                                  pbrockway2 wrote:
                                  According to [Importing Java Packages, Classes|http://java.sun.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html#jsimport] in the Java Scripting Programmer's Guide":

                                  The Packages global variable can be used to access Java packages. Examples: Packages.java.util.Vector, Packages.javax.swing.JFrame. Please note that "java" is a shortcut for "Packages.java". There are equivalent shortcuts for javax, org, edu, com, net prefixes, so pratically all JDK platform classes can be accessed without the "Packages" prefix.

                                  Note that java.lang is not imported by default (unlike Java) because that would result in conflicts with JavaScript's built-in Object, Boolean, Math and so on.
                                  So a rather mundane explanation rather than an odd one.