Adding a property to a java object in javascript

342 views
Skip to first unread message

Jim Johnson

unread,
Dec 9, 2011, 1:08:48 PM12/9/11
to mozilla-rhino
I'm doing some investigative work to potentially replace a home grown
ANTLR based grammar with Javascript via Rhino to be embedded in an
application. One of the requirements of doing this is I have to be
able to take the existing ANTLR stuff and support it 100% in the Rhino
implementation, it's a non-starter to go back and re-write things to
be pure javascript. This isn't a big deal so far because our ANTLR
based stuff is pretty run of the mill.

One thing I want to do is take java objects I have, insert them into
the Rhino scope, and then append some kind of helper properties to
them that reference things inside the java object in a specific way.
I'll try to type the example up to make this clear.

public class Foo {
private String name;
private Bar[] bar;
//Getters & setters
}

public class Bar {
private String id;
//getters & setters
}

Let's say I have an object structure of something like:
Foo:
name = "Jim"
Bar[0].id = "ID0"
Bar[1].id = "ID1"

Using Context.javaToJS & scope.put I can add a "foo" object to my
rhino scope so that in JS I can do things like
foo.name
foo.bar[0].id

That all works great! Now my problem is that I would also like to be
able to do the following in javascript:

foo.bar_ID0

And have that return to me the Bar object for "Bar[0]" in my structure
above. I've tried a few different things like put & putProperty on my
Context.javaToJS object, but I always end up w/ an exception that says
something like:

org.mozilla.javascript.EvaluatorException: Java class "Foo" has no
public instance field or method named "bar_ID0"

Is there a way to do what I want to do? I essentially want to make up
some faux getters in my javascript object to directly access some
nested objects. The problem is that the getters will have a dynamic
name & number, so I can't really create getBar_ID0 on my java class
itself.

Thanks for any help anyone can provide!

-Jim

Jim Johnson

unread,
Dec 9, 2011, 2:42:22 PM12/9/11
to mozilla-rhino
Alright, more tinkering has lead to a solution. On my
NativeJavaObject I simple did a setPrototype(new NativeObject());

I'm not sure if this is really the right way to do this but it appears
to work. I'd still love to hear from someone with more experience if
this is a good idea or if there's a better way to do what I want, or
if what I'm aiming for is complete madness. Thanks!

-Jim

Jeb Beich

unread,
Dec 9, 2011, 2:52:31 PM12/9/11
to mozill...@googlegroups.com
From the repl I tried:

var foo = new java.lang.String("foo");
var bar = {};
for (thing in foo) bar[thing] = foo[thing];

..thinking maybe proxying all the calls from bar -> foo would let
custom stuff happen on bar. Instead, I just had a bunch of stack
overflow issues. no luck...

--
Jeb Beich
http://www.red-source.net/jeb

Reply all
Reply to author
Forward
0 new messages