Bug report: can't call static methods on a Java class instance

Attila Szegedi attila.szegedi at oracle.com
Wed Oct 9 08:25:26 PDT 2013


On Oct 9, 2013, at 4:58 PM, Tal Liron <tal.liron at threecrickets.com> wrote:

> I understand the workaround, but again I fail to see the rationale behind Nashorn's overly-strict interface  to Java. What's wrong with supporting the shorthand in Nashorn, especially when Rhino behaves as JavaScript programmers would expect?

I'm not sure what expectation a JavaScript programmer could intrinsically have with regard to the functionality of the Java platform. (E.g. a concept of instance vs. static members not sharing a namespace on an object). Java platform and JavaScript are independent, so a theoretical "JavaScript programmer" should have no a priori expectations with regard to how platform integration features work. A "JavaScript programmer used to work with Rhino" is a different kind of creature, of course. 

Implementing functionality on the border of a language and its host platform will always be a tradeoff between leaning more towards one side or more towards the other. Where decisions need to be made, they will always reflect the convictions of its designers. My conviction is that exposing static members through instances is a sloppy mashing together of otherwise separate namespaces, hence I chose not to enable it. (Using instances to invoke static methods is also a discouraged practice in Java, where it additionally carries an unnecessary null dereference risk). I actually frowned upon Rhino supporting that.

I believe that where I had to make design decisions, I made them in the direction of helping people write more maintainable and clear code in the long run, even if it means not having some, as you'd say "convenient shortcuts". At the end of the day, Nashorn isn't Rhino. It's quite similar in lots of regards, but when needed, we deliberated and went with different choices when we felt we need to. It's a different runtime. (Notwithstanding, I think we'll do something about the array conversions…)

Attila.

> 
> On 10/09/2013 10:55 PM, Attila Szegedi wrote:
>> Yup. Static methods can't be invoked on instances. This is by design. The following will work:
>> 
>> 	Java.type("MyClass").myMethod()
>> 
>> of course, you can reuse it as:
>> 
>> 	var MyClass = Java.type("MyClass")
>> 	...
>> 	MyClass.myMethod()
>> 
>> As a matter of fact, you can even get the method and invoke it later:
>> 
>> 	var myMethod = Java.type("MyClass").myMethod
>> 	...
>> 	myMethod()
>> 
>> This will also work:
>> 
>> 	myInstance.class.static.myMethod()
>> 
>> as "static" is a synthetic property on java.lang.Class objects that returns the object representing their static facet (basically, containing static members and acting as a constructor - the same object Java.type() returns).
>> 
>> Attila.
>> 
>> On Oct 9, 2013, at 4:13 PM, Tal Liron <tal.liron at threecrickets.com> wrote:
>> 
>>> If we have a Java class:
>>> 
>>> class MyClass {
>>>  public static void myMethod();
>>> }
>>> 
>>> And in JavaScript try:
>>> 
>>> myInstance.myMethod()
>>> 
>>> Then we would get an exception that looks something like this:
>>> 
>>> myscript.js:... TypeError: MyClass at ... has no such function "myMethod"
>>>    at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:56)
>>>    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:212)
>>>    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:184)
>>>    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:171)
>>>    at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.linkBean(NashornBottomLinker.java:113)
>>>    at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.getGuardedInvocation(NashornBottomLinker.java:68)
>>>    at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124)
>>>    at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:138)
>>>    at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:232)
>>>    at jdk.nashorn.internal.scripts.Script$default.runScript(component/services/sincerity/version/default.js:6)
>>>    at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:527)
>>>    at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:204)
>>>    at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:367)
>>> 
> 



More information about the nashorn-dev mailing list