Discussion:
Extending a Java class
Axel Dörfler
2018-09-27 15:23:42 UTC
Permalink
Hi there,

I'm trying to extend an Abstract java base class, and add a new method
to it. However, that doesn't seem to work.

I've tried it like this:

var object = Java.extend(MyType, {
newFunction: function(argument) {
...
}
});

And that:

MyType.newFunction = function(...) {...};
var object = new MyType;

And also:

var object = new MyType({
newFunction: ...
});

While it will all happily accept those things, none of them worked.
When I try to call the method, it'll say:
TypeError: object.newFunction is not a function

Do you have any idea how I could solve this? Overriding an existing
method works easily, adding a new method does not (at least not this way).

Kind regards,
Axel Dörfler.
Sundararajan Athijegannathan
2018-09-28 09:34:41 UTC
Permalink
It is hard to say what went wrong without looking at your full sample/test.

Openjdk wiki page explains Java.extend function is here:

https://wiki.openjdk.java.net/display/Nashorn/Nashorn%2Bextensions#Nashornextensions-java_extend

You may want to take a look at nashorn samples that use Java.extend such
these ->

http://hg.openjdk.java.net/jdk/jdk/file/7bd8d6b011c9/src/sample/nashorn/flexijson.js
http://hg.openjdk.java.net/jdk/jdk/file/7bd8d6b011c9/src/sample/nashorn/resourcetrysuggester.js

Hope this helps,
-Sundar
Post by Axel Dörfler
Hi there,
I'm trying to extend an Abstract java base class, and add a new method
to it. However, that doesn't seem to work.
var object = Java.extend(MyType, {
newFunction: function(argument) {
...
}
});
MyType.newFunction = function(...) {...};
var object = new MyType;
var object = new MyType({
newFunction: ...
});
While it will all happily accept those things, none of them worked.
TypeError: object.newFunction is not a function
Do you have any idea how I could solve this? Overriding an existing
method works easily, adding a new method does not (at least not this way).
Kind regards,
Axel Dörfler.
Axel Dörfler
2018-09-28 09:49:11 UTC
Permalink
Post by Sundararajan Athijegannathan
It is hard to say what went wrong without looking at your full sample/test.
http://hg.openjdk.java.net/jdk/jdk/file/7bd8d6b011c9/src/sample/nashorn/resourcetrysuggester.js
Thanks! This usage suggests that it should actually work.

Here is my full example stripped down to the bare minimum:

----------------8<----------------
var MatcherEditor =
Java.type("ca.odell.glazedlists.matchers.AbstractMatcherEditor");

var filter = new (Java.extend(MatcherEditor)) {
setEnabled: function(enabled) {
if (enabled) {
fireMatchNone();
} else {
fireMatchAll();
}
}
};
filter.setEnabled(true);
----------------8<----------------

The error is:
TypeError: filter.setEnabled is not a function in <eval> at line number 13

For the Glazedlists class used, see here:
http://static.javadoc.io/net.java.dev.glazedlists/glazedlists_java16/1.10.0/ca/odell/glazedlists/matchers/AbstractMatcherEditor.html

Source:
https://github.com/glazedlists/glazedlists/blob/master/core/src/main/java/ca/odell/glazedlists/matchers/AbstractMatcherEditor.java

That looks like a bug to me. But if there's a workaround, I'll take it :-)

Kind regards,
   Axel Dörfler.
Sundararajan Athijegannathan
2018-10-01 03:00:08 UTC
Permalink
Hi,

In your example, it seems you're trying to add a new method to the
subtype created in script. That is not supported. You can override
existing methods of superclass - but not add a new method to the Java
type. Note that all super methods (including protected ones) are
available via Java.super. For example, you can invoke
Java.super(filter).fireMatchNode(). So the workaround for this case
would be add utility function outside for "setEnabled".

Hope this helps,
-Sundar
Post by Axel Dörfler
Post by Sundararajan Athijegannathan
It is hard to say what went wrong without looking at your full sample/test.
http://hg.openjdk.java.net/jdk/jdk/file/7bd8d6b011c9/src/sample/nashorn/resourcetrysuggester.js
Thanks! This usage suggests that it should actually work.
----------------8<----------------
var MatcherEditor =
Java.type("ca.odell.glazedlists.matchers.AbstractMatcherEditor");
var filter = new (Java.extend(MatcherEditor)) {
setEnabled: function(enabled) {
if (enabled) {
fireMatchNone();
} else {
fireMatchAll();
}
}
};
filter.setEnabled(true);
----------------8<----------------
TypeError: filter.setEnabled is not a function in <eval> at line number 13
http://static.javadoc.io/net.java.dev.glazedlists/glazedlists_java16/1.10.0/ca/odell/glazedlists/matchers/AbstractMatcherEditor.html
https://github.com/glazedlists/glazedlists/blob/master/core/src/main/java/ca/odell/glazedlists/matchers/AbstractMatcherEditor.java
That looks like a bug to me. But if there's a workaround, I'll take it :-)
Kind regards,
Axel Dörfler.
Axel Dörfler
2018-10-02 10:22:26 UTC
Permalink
Hi Sundar,
Post by Sundararajan Athijegannathan
In your example, it seems you're trying to add a new method to the
subtype created in script. That is not supported. You can override
existing methods of superclass  - but not add a new method to the Java
type.
Bummer! resourcetrysuggester.js added new fields to a Java type, so I
thought it should work.
Post by Sundararajan Athijegannathan
Note that all super methods (including protected ones) are
available via Java.super. For example, you can invoke
Java.super(filter).fireMatchNode(). So the workaround for this case
would be add utility function outside for "setEnabled".
This does sound like an acceptable work-around, however, it doesn't seem
to work:
TypeError: Java.super(filter).fireMatchNone is not a function

I guess there is no way to call protected methods from JavaScript then?
Well, I guess reflection will work.

Kind regards,
Axel.
Sundararajan Athijegannathan
2018-10-03 12:32:06 UTC
Permalink
protected methods of super class are made public in the generated script
subclass. Java.super should have worked. If you can submit a simpler
test case, it may be possible to see what's happening..

Thanks
-Sundar
Post by Axel Dörfler
Hi Sundar,
Post by Sundararajan Athijegannathan
In your example, it seems you're trying to add a new method to the
subtype created in script. That is not supported. You can override
existing methods of superclass - but not add a new method to the
Java type.
Bummer! resourcetrysuggester.js added new fields to a Java type, so I
thought it should work.
Post by Sundararajan Athijegannathan
Note that all super methods (including protected ones) are available
via Java.super. For example, you can invoke
Java.super(filter).fireMatchNode(). So the workaround for this case
would be add utility function outside for "setEnabled".
This does sound like an acceptable work-around, however, it doesn't
TypeError: Java.super(filter).fireMatchNone is not a function
I guess there is no way to call protected methods from JavaScript
then? Well, I guess reflection will work.
Kind regards,
Axel.
Loading...