JSObject.call(), closures, JS anonymous function references etc

R

Richard Maher

Hi,

Using netscape.javascript.JSObject (LiveConnect) I want/need to pass a
Function Reference to my Java Applet so that it can either call that
directly, or pass it to a static JavaScript function that will then redirect
the call to the appropriate anonymous function that formed a closure.

Please forgive me if the terminology is not strictly correct, but I hope you
can still understand what I'm trying to do.

I thought the second argument to JSObject.call could be an array of Strings
*or* Objects but trying to get a JavaScript object (or a reference/pointer
to it) to survive the Java Applet membrane (without some sort of
serialize/deserialize) is proving difficult. Am I missing something obvious?
Does anyone have a small example I can look at?

Maybe it's as easy as the first argument to JSObject.call can be a
JavaScript VARiable? I'll give it a go. . .

Cheers Richard Maher

//This is called from the "onload" event
function load() {
myFunc = setClosure();
myFunc();
chan = document.getElementById("AnonCallApplet");
return;
}
// This is called from the Applet
function jsMethod(javaInt, javaFunc) {
alert('Integer ' + javaInt);
alert('JavaFunc ' + javaFunc.toString());
javaFunc();
return;
}

function setClosure() {
var lclNum = 0;
return function(){
lclNum++;
alert("lclNum = " + lclNum);
}
}
// This is called by some user-driven event (onchange, onclick. . ).
function callApplet() {
alert(myFunc.toString());
chan.javaMethod(step, myFunc)
return true;
}

//Here's the Applet

import java.applet.Applet;
import java.io.IOException;
import netscape.javascript.JSObject;
import netscape.javascript.JSException;

public class AnonCallApplet extends Applet {

private JSObject browser;
private static int sumNum = 0;
private int addNum;

public void init(){
try {
browser = JSObject.getWindow(this); }
catch (netscape.javascript.JSException e) {
e.printStackTrace(); }
catch (Exception e) {
e.printStackTrace(); }
}

public void javaMethod (String jsNum, String jsFunc) {

addNum = Integer.parseInt(jsNum);

sumNum += addNum;
Object args[] = {(Object)new Integer(sumNum), (Object)jsFunc};
try {
browser.call("jsMethod", args);}
catch (JSException e){
System.out.println("Error when calling jsMethod()"); }
}

public void destroy() {
super.destroy();
}
}
 
R

Richard Maher

Hi,

I replaced the pilot-error: -
public void javaMethod (String jsNum, String jsFunc) {
with
public void javaMethod (String jsNum, Object jsFunc) {

and it seems to be giving me a bit more. Sorry for the distraction.

Cheers Richard Maher
 
R

Richard Maher

Hi again,

Any advice regarding problems/solutions to the following
requirements-specification would be appreciated.

a) I want to implement an Asynchronous I/O strategy between my Java Applet's
TCP/IP Socket and my JavaScript anonymous function instances. (So that they
fulfill the role of "Asynchronous System Traps - ASTs" or "Asynchronous
Call-backs")

b) My JavaScript will call an Applet method to perform synchronous writes to
the Socket and I plan to have a separate thread constantly reading for
responses.

c) I don't want to lock up the browser EDT while I'm waiting for a Read to
complete and have previously used a single-thread and the Socket Timeout
method as a sort of delayed poll which let user events/clicks through every
"n" seconds. What I want to do this time is use the separate thread to
invoke JSObject.call() for each message received. No problem with using a
static JavaScript function (I've done so successfully with async UDP
messages) but, as there may be many messages received per message sent and
there is no restriction on additional messages/requests (or message types)
being sent before all messages/responses for a prior message have been read,
I was hoping to use closures and anonymous function instances to preserve
and pass message-specific parameters to asynchronous read-completion
routine/callback.

d) The good news is the requests will be on a single connection-oriented
Socket and will be processed on a FIFO basis, so storing parameter objects
in an JavaScript/Java Array certainly seems doable. (I'd pass a serial
number with the outgoing message and check it against what we're expecting
to read next and use push() and shift() to manage the Array)

e) I have to admit to being a bit bamboozled as to whether Java has received
the function instance by reference, and once the JS function's local
variable that passed the reference to Java has RETURNed (or that local
variable re-assigned) and nobody on the JavaScript side is left referencing
that instance of the function, that the garbage-collector might clean-up the
function even though my Applet would be expecting to call it some time in
the future.

f) Even if longevity was assured, stuffed if I know of a method that would
deserialize the function (or function reference) so that it could accompany
the outgoing message to the remote 3GL routine and come back in a reply and
be serialized into a useful form. As a procedural guy at heart, to me it
looks like a great case for malloc, pointer, free but hopefully someone can
show me the optimal OO way of achieving this.

g) Would the performance of a JavaScript Array that acts like a queue and
gets fed from the tail and diminished from the head, degrade over time? (At
least with an Array I could use a static/named JS function and keep it
simple.)

I guess the first thing I should've asked is has anyone done this or have an
example? It is my understanding that Async i/o would appear to be "new" in
Java 7 and if that is the case then I'm guessing there's a definite
requirement but perhaps no historic solution at present?

Cheers Richard Maher

Richard Maher said:
Hi,

I replaced the pilot-error: -
public void javaMethod (String jsNum, String jsFunc) {
with
public void javaMethod (String jsNum, Object jsFunc) {

and it seems to be giving me a bit more. Sorry for the distraction.

Cheers Richard Maher

Richard Maher said:
Hi,

Using netscape.javascript.JSObject (LiveConnect) I want/need to pass a
Function Reference to my Java Applet so that it can either call that
directly, or pass it to a static JavaScript function that will then redirect
the call to the appropriate anonymous function that formed a closure.

Please forgive me if the terminology is not strictly correct, but I hope you
can still understand what I'm trying to do.

I thought the second argument to JSObject.call could be an array of Strings
*or* Objects but trying to get a JavaScript object (or a reference/pointer
to it) to survive the Java Applet membrane (without some sort of
serialize/deserialize) is proving difficult. Am I missing something obvious?
Does anyone have a small example I can look at?

Maybe it's as easy as the first argument to JSObject.call can be a
JavaScript VARiable? I'll give it a go. . .

Cheers Richard Maher

//This is called from the "onload" event
function load() {
myFunc = setClosure();
myFunc();
chan = document.getElementById("AnonCallApplet");
return;
}
// This is called from the Applet
function jsMethod(javaInt, javaFunc) {
alert('Integer ' + javaInt);
alert('JavaFunc ' + javaFunc.toString());
javaFunc();
return;
}

function setClosure() {
var lclNum = 0;
return function(){
lclNum++;
alert("lclNum = " + lclNum);
}
}
// This is called by some user-driven event (onchange, onclick. . ).
function callApplet() {
alert(myFunc.toString());
chan.javaMethod(step, myFunc)
return true;
}

//Here's the Applet

import java.applet.Applet;
import java.io.IOException;
import netscape.javascript.JSObject;
import netscape.javascript.JSException;

public class AnonCallApplet extends Applet {

private JSObject browser;
private static int sumNum = 0;
private int addNum;

public void init(){
try {
browser = JSObject.getWindow(this); }
catch (netscape.javascript.JSException e) {
e.printStackTrace(); }
catch (Exception e) {
e.printStackTrace(); }
}

public void javaMethod (String jsNum, String jsFunc) {

addNum = Integer.parseInt(jsNum);

sumNum += addNum;
Object args[] = {(Object)new Integer(sumNum), (Object)jsFunc};
try {
browser.call("jsMethod", args);}
catch (JSException e){
System.out.println("Error when calling jsMethod()"); }
}

public void destroy() {
super.destroy();
}
}
 
J

Jon Gomez

I read your message on the Javascript newsgroup. I'm new to Javascript
and I follow the newsgroup as an effort to be exposed to and learn about
the language. Therefore, I am limited to asking questions about what
you are doing, or checking things that seem strange to me, when it comes
to Javascript. Someone else, I hope, will give you more direct help.

Richard said:
a) I want to implement an Asynchronous I/O strategy between my Java Applet's
TCP/IP Socket and my JavaScript anonymous function instances. (So that they
fulfill the role of "Asynchronous System Traps - ASTs" or "Asynchronous
Call-backs")

Do you mean the following?

You're using Java as a bridge to network communications for Javascript?
The Java applet reads in data over network, as it comes. It then passes
it to the Javascript code, whenever the data arrives. The Javascript
then acts on or perhaps stores this data for later processing?


If the data is being stored by the Javascript, then doesn't that imply
that you have to set up safeguards against concurrent data modification?
How will you protect yourself against this?

I don't know of any way to do this in Javascript in browsers. There is
a future reserved word "synchronized" mentioned for EMCAScript in EMCA
262, but I don't think it exists in any version of Javascript. Maybe
there is a way? Anyone?

Would it be better, perhaps, to handle the issue of concurrent writes to
the incoming data buffer on the applet side, storing data there, etc.?
b) My JavaScript will call an Applet method to perform synchronous writes to
the Socket and I plan to have a separate thread constantly reading for
responses.
Okay...


c) I don't want to lock up the browser EDT while I'm waiting for a Read to
complete and have previously used a single-thread and the Socket Timeout
method as a sort of delayed poll which let user events/clicks through every
"n" seconds.

Okay... Just by the by, have you thought about polling available()
instead of just relying on socket timeouts? I'm pretty sure there's no
reason that it needs to be a blocking operation. See
Socket.getInputStream() and InputStream.available().
What I want to do this time is use the separate thread to
invoke JSObject.call() for each message received. No problem with using a
static JavaScript function (I've done so successfully with async UDP
messages) but, as there may be many messages received per message sent and
there is no restriction on additional messages/requests (or message types)
being sent before all messages/responses for a prior message have been read,
I was hoping to use closures and anonymous function instances to preserve
and pass message-specific parameters to asynchronous read-completion
routine/callback.

You still have to keep track of those closures, then, somehow, and so
the concurrent modification problem doesn't go away. As for using
closures to separate messages, why?

Hmmm... what about, instead of using the AST paradigm, have the
Javascript poll the applet, using window.setInterval() (See Mozilla
documentation) to have the Javascript polling function called every so
often? Or have the applet do the calling at intervals with a bit of
data at a time to be processed, not stored? Would any of these work?
d) The good news is the requests will be on a single connection-oriented
Socket and will be processed on a FIFO basis, so storing parameter objects
in an JavaScript/Java Array certainly seems doable. (I'd pass a serial
number with the outgoing message and check it against what we're expecting
to read next and use push() and shift() to manage the Array)
Okay...

e) I have to admit to being a bit bamboozled as to whether Java has received
the function instance by reference, and once the JS function's local
variable that passed the reference to Java has RETURNed (or that local
variable re-assigned) and nobody on the JavaScript side is left referencing
that instance of the function, that the garbage-collector might clean-up the
function even though my Applet would be expecting to call it some time in
the future.

Looking through the Liveconnect documentation at

https://jdk6.dev.java.net/plugin2/liveconnect/

there is a guarantee that Java objects passed to Javascript won't be
garbage collected by Java as long as JS holds references (2.6), but I
couldn't find anything the other way around, nor at

https://developer.mozilla.org/en/LiveConnect

which makes it sound like a moving target, anyway.

If you are worried, why not just keep an active reference to anything
you currently need and clear it as necessary?

Did you have this concern because you wanted to keep the generated
closures stored in Java but not referenced in Javascript? That is
possibly getting needlessly complicated.

f) Even if longevity was assured, stuffed if I know of a method that would
deserialize the function (or function reference) so that it could accompany
the outgoing message to the remote 3GL routine and come back in a reply and
be serialized into a useful form. As a procedural guy at heart, to me it
looks like a great case for malloc, pointer, free but hopefully someone can
show me the optimal OO way of achieving this.

Does this mean you trying to send Javascript functions over the network?
Why? Couldn't you just use some kind of identifier for the function,
and just have both sides aware of the function already? Or send pure
data instead of functions? I have visions of you using eval() and
storing the function declarations as strings. I bet someone in the
comp.lang.javascript group will find the mere mention horrible.

Malloc? Free? Pointers? Are you implying something about
"serializing" and sending C functions over the network? Really? That's
interesting but rather bizarre. I can think of ways to do it, but not a
one is portable, and it seems really awkward.
g) Would the performance of a JavaScript Array that acts like a queue and
gets fed from the tail and diminished from the head, degrade over time? (At
least with an Array I could use a static/named JS function and keep it
simple.)
I guess the first thing I should've asked is has anyone done this or have an
example? It is my understanding that Async i/o would appear to be "new" in
Java 7 and if that is the case then I'm guessing there's a definite
requirement but perhaps no historic solution at present?

Hmmmmmmmm....

I'm curious why Javascript is involved at all? Why aren't you, say,
using pure Java? I imagine you have a reason--I'm just asking what it is.


Jon.
 
A

Arne Vajhøj

Richard said:
Using netscape.javascript.JSObject (LiveConnect) I want/need to pass a
Function Reference to my Java Applet so that it can either call that
directly, or pass it to a static JavaScript function that will then redirect
the call to the appropriate anonymous function that formed a closure.

Please forgive me if the terminology is not strictly correct, but I hope you
can still understand what I'm trying to do.

I thought the second argument to JSObject.call could be an array of Strings
*or* Objects but trying to get a JavaScript object (or a reference/pointer
to it) to survive the Java Applet membrane (without some sort of
serialize/deserialize) is proving difficult. Am I missing something obvious?
Does anyone have a small example I can look at?

Maybe it's as easy as the first argument to JSObject.call can be a
JavaScript VARiable? I'll give it a go. . .
// This is called from the Applet
function jsMethod(javaInt, javaFunc) {
alert('Integer ' + javaInt);
alert('JavaFunc ' + javaFunc.toString());
javaFunc();
return;
}

It would have been slightly easier if you had told us what was happening
when this code was executed.

But I assume you have a problem with the type of javaFunc.

Maybe there are some tricky way of doing this the right way.

But I know you can do it with eval. Pass a string from JS to Java,
pass a string from Java to JS and then call it using eval.

Not nice, but it will work.

Arne
 
A

Arne Vajhøj

Richard said:
c) I don't want to lock up the browser EDT while I'm waiting for a Read to
complete and have previously used a single-thread and the Socket Timeout
method as a sort of delayed poll which let user events/clicks through every
"n" seconds. What I want to do this time is use the separate thread to
invoke JSObject.call() for each message received. No problem with using a
static JavaScript function (I've done so successfully with async UDP
messages) but, as there may be many messages received per message sent and
there is no restriction on additional messages/requests (or message types)
being sent before all messages/responses for a prior message have been read,
I was hoping to use closures and anonymous function instances to preserve
and pass message-specific parameters to asynchronous read-completion
routine/callback.

d) The good news is the requests will be on a single connection-oriented
Socket and will be processed on a FIFO basis, so storing parameter objects
in an JavaScript/Java Array certainly seems doable. (I'd pass a serial
number with the outgoing message and check it against what we're expecting
to read next and use push() and shift() to manage the Array)

e) I have to admit to being a bit bamboozled as to whether Java has received
the function instance by reference, and once the JS function's local
variable that passed the reference to Java has RETURNed (or that local
variable re-assigned) and nobody on the JavaScript side is left referencing
that instance of the function, that the garbage-collector might clean-up the
function even though my Applet would be expecting to call it some time in
the future.

f) Even if longevity was assured, stuffed if I know of a method that would
deserialize the function (or function reference) so that it could accompany
the outgoing message to the remote 3GL routine and come back in a reply and
be serialized into a useful form. As a procedural guy at heart, to me it
looks like a great case for malloc, pointer, free but hopefully someone can
show me the optimal OO way of achieving this.

As suggested in previous reply. Just send a string with the
function name and use eval in the response processing JS.

JS->Java->JS or JS->Java->server->Java->JS should not matter.

Arne
 
R

Richard Maher

Hi Jon,

Jon Gomez said:
I read your message on the Javascript newsgroup. I'm new to Javascript
and I follow the newsgroup as an effort to be exposed to and learn about
the language. Therefore, I am limited to asking questions about what
you are doing, or checking things that seem strange to me, when it comes
to Javascript.

No worries, but if I had the answers I wouldn't be asking here :)
Someone else, I hope, will give you more direct help.

Me too.
Do you mean the following?

You're using Java as a bridge to network communications for Javascript?
The Java applet reads in data over network, as it comes. It then passes
it to the Javascript code, whenever the data arrives.
Yep.

The Javascript
then acts on or perhaps stores this data for later processing?

Anything permissible by JavaScript or Flex in a browser.
If the data is being stored by the Javascript, then doesn't that imply
that you have to set up safeguards against concurrent data modification?
How will you protect yourself against this?

Currently (with the Socket and accompanying paraphernalia declared as
instance variables, and not a static class variable in sight) there is only
ever one thread reading and writing. Although I am also looking at providing
a second option/solution with the Scoket as a static class variable, where I
will still have only one thread reading the Socket (across all browser
instances/tabs for a given application (same JRE instance issues
notwithstanding)) but many writers. I plan to use Java's lovely
"synchronized" methods/blocks to manage concurrency and contention.

But more on that idea/strategy elsewhere and later.

BTW, it is my understanding that even with the complete rework of the JRE
with Java 6 and Applets in their own threads (OS X got 6 yet?) there are
still implicit synchronization/scheduling restrictions that one can rely on.
(Personally, I have never written a AppletX-call->JS-call->AppletX type
thing but the docs seem to indicate is doable and also when it would lock
up - curious).
I don't know of any way to do this in Javascript in browsers. There is
a future reserved word "synchronized" mentioned for EMCAScript in EMCA
262, but I don't think it exists in any version of Javascript. Maybe
there is a way? Anyone?

Do it in Java instead.
Would it be better, perhaps, to handle the issue of concurrent writes to
the incoming data buffer on the applet side,
Yes.

storing data there, etc.?

No data "storing".
Okay... Just by the by, have you thought about polling available()
instead of just relying on socket timeouts? I'm pretty sure there's no
reason that it needs to be a blocking operation. See
Socket.getInputStream() and InputStream.available().

Polling is anathema to me! But as described above, I have previously used
the setSoTimeout(msecs) as a way to mitigate the extreme badness of polling
while still opening a window for EDT processing.
You still have to keep track of those closures, then, somehow, and so
the concurrent modification problem doesn't go away. As for using
closures to separate messages, why?

Each message has message-specific variables and context so closures seemed,
to me at least, like a useful place to stick that context until the AST
fired. It's now looking like I'll pass a static JS function name and
variables to the Applet and that context can make the round-trip to the
remote server and back. Bit of stuffing arround to configure and arguments
array that can be function-specific and limiting it to Strings and intS (or
do my own (de)serialize). On second thoughts, I'll stick with an Array of
Objects in JavaScript and checking that the serial number/identifier of the
message received from Java matches that of the first element in the array.
When there are no more reponse messages for that number the first element in
the Array is removed.

How would *you* preserve stateful, function-specific, context data so as to
be available when the response message arrived?
Hmmm... what about, instead of using the AST paradigm, have the
Javascript poll the applet, using window.setInterval() (See Mozilla
documentation) to have the Javascript polling function called every so
often? Or have the applet do the calling at intervals with a bit of
data at a time to be processed, not stored? Would any of these work?

See setSoTimeout above, and know why it is a better solution.

The simple fact is I don't want polling! That is why I am asking about
establishing ASTs in a JavaScript. So far it looks very doable. If what I
have described won't work can someone please tell me why?
Looking through the Liveconnect documentation at

https://jdk6.dev.java.net/plugin2/liveconnect/

there is a guarantee that Java objects passed to Javascript won't be
garbage collected by Java as long as JS holds references (2.6), but I
couldn't find anything the other way around, nor at

https://developer.mozilla.org/en/LiveConnect

which makes it sound like a moving target, anyway.

Thanks for the references and for lokking that up.
If you are worried, why not just keep an active reference to anything
you currently need and clear it as necessary?

Which led me to the Array construct and and grow/shrink issues? How would
*you* "keep an active reference" to a variable number of transient objects?
Some wiz-bang Mozilla Object.IncRef() perhaps?
Did you have this concern because you wanted to keep the generated
closures stored in Java but not referenced in Javascript? That is
possibly getting needlessly complicated.

I've got an indefinite number of outstanding or potential ASTs; I need
somewhere to store some context info; in the absence of "malloc and pass the
pointer", closures looked to fit the bill. But as you say, maybe it is all
too hard?
Does this mean you trying to send Javascript functions over the network?

Or ideally trying to send pointers/"references" to JavaScript functions.

You're just not getting this are you :)

There's an object (chunk of memory) that will be useful to my JavaScript
function when deciding what to do when a message finally arrives. Maybe it
has Regional info like Language, Character-set, colour. Maybe it has the
Time the request message was sent so that round-trip statistics can be
calculated, who knows? It's Application-specific!

Just trust me on this that it is not an uncommon requirement to deliver a
parameter to an AST.
Couldn't you just use some kind of identifier for the function,
and just have both sides aware of the function already?

Excellent! What's that "identifier" called (pointer?) and how do I
(de)serialize it?
Or send pure
data instead of functions?

Where I'm at is sending an index into a JavaScript Array, but am open to
better suggestions.
I have visions of you using eval() and
storing the function declarations as strings. I bet someone in the
comp.lang.javascript group will find the mere mention horrible.

An option. But I don't think it buys you anymore than static named functions
and configure the arg-lists.
Malloc? Free? Pointers? Are you implying something about
"serializing" and sending C functions over the network? Really? That's
interesting but rather bizarre. I can think of ways to do it, but not a
one is portable, and it seems really awkward.

I want (from an Java/JS/OO person) what in Java/JavaScript is analogous to
malloc, pointer, free in C.

Any takers on the performance issue?
Hmmmmmmmm....

I'm curious why Javascript is involved at all? Why aren't you, say,
using pure Java? I imagine you have a reason--I'm just asking what it is.

Why JavaScript?
Why Java?
Why Flex?
Why not RMI, or SOAP?
Why not drop Java and use RESTful Ajax/http?
Why not PHP, Perl, etc?

All good questions I suppose, for someone who cares to answer anywhere else
but here :)

Cheers Richard Maher
 
R

Richard Maher

Hi Arne,

Arne Vajhøj said:
It would have been slightly easier if you had told us what was happening
when this code was executed.

Appended below is the entire Applet and HTML (very tiny mickey-mouse
example). Just trying to see if the function reference survived the trip.
See below.
But I assume you have a problem with the type of javaFunc.

During testing I'd changed it to String and forgot to change it back again.
Type "Object" seems to be acceptable for a function reference/function
whatever it is.
Maybe there are some tricky way of doing this the right way.

I wish there was; looks sexy to me! (in a functionally worthwhile sense.)
But I know you can do it with eval. Pass a string from JS to Java,
pass a string from Java to JS and then call it using eval.

More on that in your other reply.
Not nice, but it will work.

Arne

Cheers Richard Maher

Here's the Java Applet: -

import java.applet.Applet;
import java.io.IOException;
import netscape.javascript.JSObject;
import netscape.javascript.JSException;

public class AnonCallApplet extends Applet {

private JSObject browser;
private static int sumNum = 0;
private int addNum;

public void init(){
try {
browser = JSObject.getWindow(this); }
catch (netscape.javascript.JSException e) {
e.printStackTrace(); }
catch (Exception e) {
e.printStackTrace(); }
}

public synchronized void javaMethod (String jsNum, Object jsFunc) {

addNum = Integer.parseInt(jsNum);
sumNum += addNum;

Object args[] = {(Object)new Integer(sumNum), jsFunc};
try {
browser.call("jsMethod", args);}
catch (JSException e){
System.out.println("Error when calling jsMethod()"); }
}

public void destroy() {
super.destroy();
}

// Yes, I don't want to synchronize around the JS call

Here's the web page. Enter something in either field an then move off. Try
several tabs and server browser instances: -

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>

<meta name="author" content="Richard Maher"/>
<meta name="description" content="JS Function and Applet Test"/>

<head>


<style>

body
{
margin: 0px;
background-color: white;
color: Black;
font-family: times;
font-size: 16px;
border: medium ridge;
}

</style>

<script type="text/javascript">

var step = 2;
var chan, myFunc;
var closures = 0;

function load() {
myFunc1 = setClosure();
myFunc2 = setClosure();
chan = document.getElementById("AnonCallApplet");
return;
}

function jsMethod(javaInt, javaFunc) {
alert('jsMethod Integer ' + javaInt);
javaFunc();
return;
}

function setClosure() {
closures++;
var myId = closures;
var lclNum = 0;
return function(){
lclNum++;
alert("Closure " + myId + " lclNum = " + lclNum);
}
}

function callApplet() {
alert(myFunc.toString());
chan.javaMethod(step, myFunc);
return true;
}

</script>

</head>

<body onload="load();">

<br /><h2>Test it</h2><hr /><br />

<form name="display" style="margin-left: 100px;">

<input
type="text"
onchange="chan.javaMethod(step, myFunc1)";
style="text-align: Left;"
name="divNode"
size=6
/>

<input
type="text"
onchange="chan.javaMethod(step, myFunc2)";
style="text-align: Left;"
name="next"
size=10
/>
</form>
<script type="text/javascript">

var appletDef = navigator.appName;

if (appletDef == "Microsoft Internet Explorer")
document.write
(
'<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ',
'width= "0" height= "0" id="AnonCallApplet">',
// '<param name="archive"
value="tier3.jar">',
// '<param name="codebase" value="http">',
'<param name="code"
value="AnonCallApplet">',
'<param name="mayscript" value="yes">',
'<param name="scriptable" value="true">',
'</object>'
);
else
document.write
(
'<object classid="java:AnonCallApplet.class" ',
'type="application/x-java-applet" ',
'width= "0" height= "0" id="AnonCallApplet">',
// '<param name="archive"
value="tier3.jar">',
// '<param name="codebase"
value="http://alpha/">',
'<param name="code"
value="AnonCallApplet">',
'<param name="mayscript" value="yes">',
'<param name="scriptable" value="true">',
'</object>'
);

</script>

</body>

</html>
 
R

Richard Maher

Hi Arne,
As suggested in previous reply. Just send a string with the
function name and use eval in the response processing JS.

Do you mean when Jon said this: -
Were you suggesting storing and eval-ing the "function declarations" also,
or quoting something else about passing the "function name"?

Anyway, not that anyone's a huge fan of eval() and regardless of that why in
this case would you opt for calling a JavaScript function that executes an
eval(functionParam) as opposed to a Java
JSObject.eval(StringAfterRoundTrip)? A bit "better" where at least some of
the value-added function verbs/declarations and data are in the main HTML/JS
file? Pre-parsed? Only half pregnant :) Never used JSObject .eval() but I'm
guessing that it does what JS.eval() does? (Never used JavaScript.eval()
either.)

Also, what am I gaining by imposing an eval() requirement in Function X that
couldn't be functionally achieved by just manipulating its parameters. IOW,
for a specific application it maybe useful for its JS function to
eval(param3) but for others function parameters 3 and 4 being strings and 5
the string representation of an int could suffice.

(Obviously the messageReceived parameter has to mandate in there somewhere
:)
JS->Java->JS or JS->Java->server->Java->JS should not matter.

Surley one requires (de)serialization and the other does not? This matters
heaps to me! My kingdom for a generic 32 (or event 64) bit pointer :-(

Anyway, I think these are the options so far: -

1a) Pass whatever context info that is needed as a string and, on return,
eval() it inside a variable (name-selected) JavaScript function. (Or perhaps
JSObject.eval())

1b) Pass whatever context-info is needed as strings and, on return, massage
the "arguments" array to a variable (name-selected) function.

2) Maintain a JavaScript Array of references to function instances (or other
complex Objects), one entry for each message sent. Fed from the tail and
removed from the head.

3) (de)Serialize a mythical pointer to an anonymous function/closure, and
pray that the JavaScript GC won't zap it before my Java Applet calls it.

Before consigning "3" to the dust-bin, let me just say that I really, really
liked the idea a lot!

I like "1b" but if "1a" has real advantages then I'm happy to hear them.

"2" is more along the lines of what I was trying to achieve but having to
maintain that queue-like Array (especially if the Socket is to be shared
among pages on different tabs and/or browser instances) requires something
to link-up several receieved messages and check that they were meant for
element[0]. (I'll ask about the possibility of gaps later on an inter-tab
question. . .)

So 1, 2 or 3? (And if 1 do you prefer "a" or "b"?)

Any thoughts/arguments like: -
"Arrays start to fragment and degrade",
"Not all context info can be expressed as a simple String",
"eval() is pronounced Evil",
"Collections are just fine",
"Keep it simple",
"Which one comes in blue?"

Cheers Richard Maher
 
R

Richard Maher

Hi,

For some time (ever since a guy called Bojan Nemec told me about it :) I've
been toying with the idea of my Java Applet declaring its TCP/IP Socket as a
static class-variable instead of an instance-variable, and on each
invocation (new page, new tab, or new browser) the init() would check to see
if the Socket was already connected (and in my case User Authorization
completed) and, if so, skip that bit. Where I think it would be useful is
when there is a Control-Panel/Dashboard requirement, similar to what Arne
and another poster were discussing recently, where each browser "tab" was a
different set of instrumentation/view. All pages being servered by a single,
secure, feature-rich, connection-oriented, context-laden, and
high-performance Socket.

NB: If this is simply *just not doable* then please let me know now before I
spend a few days trying to get it to work :)

Some issues that spring to mind (that I hope someone can offer advice on)
are: -

1) To continue my "single reader-thread to oodles of writer-threads" model,
I'm really hoping that JSObject.getWindow() will return something that is
both unique to each web-page instance (wherever it is hosted) and the
accessible from my single reader thread. I plan to store it in a Linked-List
along with a Unique Id that will accompany the user request-messages on
their trips to the server and when they comes back, I'll search the list for
matching index-number, get the corresponding JSObject, and then perform the
..call(). (Perhaps JSObject is serializable? No wait - there's a toString()
method! What's the reverse? I'm guessing you can't simply cast the String as
JSObject.)

2) I hope that JSObject.getWindow() returns the same thing in the Applet's
destroy() method as it does in the int() method so that I can do a reverse
lookup. Hey, there's a JSObject.equals() method - You bewdy!

3) The whole concept of Socket-Hijacking a la mode de Session-Hijacking, I'm
gonna leave to one side for the moment. I'm relying on Java to prohibit the
manual construction/fudge of a Java Socket on top of just any old socket,
and the operating system to protect a socket in one process/image from
access by another unprivileged process/image.

4) How do I prevent just any old page from including an <object> tag for my
Applet and gaining access to the (possibly pre-authorized) Socket? Off the
top of my head, I could store the Document Base of the first page that
actually passed authentication, and if any subsequent page comes from a
different DB then prompt for username/password again. Any other tools in the
toolbox that I can use to secure access?

5) I'll have to introduce a logout function as that functionality is
currently enforced automatically by any page-change. I guess a dialog box
with some useless Socket statistics and a logout button should suffice.
(When the number of JSObjects is reduced to zero, an automatic logout will
take place.)

6) JRE instances. Funny how IE and FF don't share the same JRE instance :)
Even with Java 6 and up, as long as the Applets ask for the same Java
version then can there be every expectation that they'll share the same JRE
instance?

7) Anything else?

Cheers Richard Maher

PS. Which Frame does the JSObject.call() activate in (let's say there is a
function with the same name in each frame of a 3-frame frameset? Current?
Top? Different JSObject.getWindow() result for each frame?

Richard Maher said:
Hi,

I replaced the pilot-error: -
public void javaMethod (String jsNum, String jsFunc) {
with
public void javaMethod (String jsNum, Object jsFunc) {

and it seems to be giving me a bit more. Sorry for the distraction.

Cheers Richard Maher

Richard Maher said:
Hi,

Using netscape.javascript.JSObject (LiveConnect) I want/need to pass a
Function Reference to my Java Applet so that it can either call that
directly, or pass it to a static JavaScript function that will then redirect
the call to the appropriate anonymous function that formed a closure.

Please forgive me if the terminology is not strictly correct, but I hope you
can still understand what I'm trying to do.

I thought the second argument to JSObject.call could be an array of Strings
*or* Objects but trying to get a JavaScript object (or a reference/pointer
to it) to survive the Java Applet membrane (without some sort of
serialize/deserialize) is proving difficult. Am I missing something obvious?
Does anyone have a small example I can look at?

Maybe it's as easy as the first argument to JSObject.call can be a
JavaScript VARiable? I'll give it a go. . .

Cheers Richard Maher

//This is called from the "onload" event
function load() {
myFunc = setClosure();
myFunc();
chan = document.getElementById("AnonCallApplet");
return;
}
// This is called from the Applet
function jsMethod(javaInt, javaFunc) {
alert('Integer ' + javaInt);
alert('JavaFunc ' + javaFunc.toString());
javaFunc();
return;
}

function setClosure() {
var lclNum = 0;
return function(){
lclNum++;
alert("lclNum = " + lclNum);
}
}
// This is called by some user-driven event (onchange, onclick. . ).
function callApplet() {
alert(myFunc.toString());
chan.javaMethod(step, myFunc)
return true;
}

//Here's the Applet

import java.applet.Applet;
import java.io.IOException;
import netscape.javascript.JSObject;
import netscape.javascript.JSException;

public class AnonCallApplet extends Applet {

private JSObject browser;
private static int sumNum = 0;
private int addNum;

public void init(){
try {
browser = JSObject.getWindow(this); }
catch (netscape.javascript.JSException e) {
e.printStackTrace(); }
catch (Exception e) {
e.printStackTrace(); }
}

public void javaMethod (String jsNum, String jsFunc) {

addNum = Integer.parseInt(jsNum);

sumNum += addNum;
Object args[] = {(Object)new Integer(sumNum), (Object)jsFunc};
try {
browser.call("jsMethod", args);}
catch (JSException e){
System.out.println("Error when calling jsMethod()"); }
}

public void destroy() {
super.destroy();
}
}
 
J

Jon Gomez

Richard Maher,

I really appreciate you taking the time to answer my questions. I shall
derive what benefit I may from your elucidation. I can see I shall need
to study ASTs.

I think for this reply, I'm going to respond by topic rather than
respond to particular quotes.


(1) Polling

You wrote: "The simple fact is I don't want polling! That is why I am
asking about establishing ASTs in a JavaScript."

Perhaps polling could still be useful in making its own opposite,
serving as a kind of internal glue hidden from the interface. However,
since you hate it enough to call it "anathema", then by all means, don't
do it. TIMTOWDI.

(2) Why not...?

Why not rock gardens and giant electromagnetic relays powered by
hamsters? :)

I was just curious. I'm not bothered by the combination. Mmmmhm... I
was recently intrigued by the charming combining of Ruby, Java, and
Processing that is Ruby-Processing. I mean to try messing with it.


(2) Associating data with functions

I would probably just create an object by hand, assign whatever
properties to it, and then assign the function in question to it. Call
the function on the object, and then the function can obtain the
contextual parameters using the "this" keyword. Use constructors if
desired. But yeah, closures too, if one wants.

(3) Stringifying functions

I was doing more research on eval(), when I ran across something not
entirely relevant but interesting nonetheless. Functions can be
converted "back" to function declaration strings. According to EMCA 262:

"An implementation-dependent representation of the function is returned.
This representation has the syntax of a FunctionDeclaration. Note in
particular that the use and placement of white space, line terminators,
and semicolons within the representation string is
implementation-dependent." (15.3.4.2)

In my tests of my IE 6 and FF 3 browsers, I found it doesn't keep track
of changes to variables, etc., after declaration, nor does it capture
any of the containing context of closures. Still, I think it's neat,
and a serialization of a function declaration if not a function with all
its actual state.

(4) Eval() and dynamic functions.

Eval can create pretty dynamically varied functions, not just static ones.

a = {
name : "func",
id : 0,
create : function() {
eval("" + this.name + this.id + "= function () { alert(\"" +
this.id + "\"); }" );
this.id++;
}
};

a.create();
a.create();
func0();
func1();
func0();

(5) Array Efficiency

I would have to run experiments. I couldn't say how to do it.

(6) Pointer, Identifier

I think an array index is a close enough approximation of a pointer
value, or if assign the function object to some named property, there
you have your identifier. Sorry I can't offer anything better.

(7) Functions and wrapping

I think I can explain why "Object jsFunc" in the second post gave you
more mileage.

Functions are objects in Javascript, which should cause them normally to
be wrapped in JSObject (EMCA section 13 & "Working with Wrappers" in the
Mozilla Liveconnect Overview). Trying to treat them as type Object in
the parameter list still results in them wrapped in JSObject. However,
if you try to treat them as String objects, then you get the result of
the original javascript object's toString(), which is not the function
object (Mozilla LC "Javascript to Java Conversions: Other Javascript
Objects").



Jon.
 
J

Jon Gomez

Richard said:
public void init(){
try {
browser = JSObject.getWindow(this); }
catch (netscape.javascript.JSException e) {
e.printStackTrace(); }
catch (Exception e) {
e.printStackTrace(); }
}

Weird...

I started doing some firsthand experimentation with Liveconnect, and I
off the bat found that when I put JSObject.getWindow(this) in the
applet's init() method, it crashed the browser (as in out to lunch). I
moved it to the paint() method and there it worked, and I could make
calls from both sides without trouble.

-----------

* Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009030422
Ubuntu/8.10 (intrepid) Firefox/3.0.7

* JDK 1.6.0_10

-----------------

import java.applet.Applet;
import java.awt.*;
import netscape.javascript.*;

public class applet extends Applet {
public void init() {
try {
JSObject.getWindow(this);
} catch(Exception e) { }
}
}

-------------------

<html><head><title>title</title></script></head><body>
<applet MAYSCRIPT=true id="app" code="applet.class" width=400
height=400>applet</applet>
</body></html>
 
A

Arne Vajhøj

Richard said:
Do you mean when Jon said this: -
Yep.

Were you suggesting storing and eval-ing the "function declarations" also,
or quoting something else about passing the "function name"?

If you have the function code on the page you only need to send
the name.
Anyway, not that anyone's a huge fan of eval() and regardless of that why in
this case would you opt for calling a JavaScript function that executes an
eval(functionParam) as opposed to a Java
JSObject.eval(StringAfterRoundTrip)? A bit "better" where at least some of
the value-added function verbs/declarations and data are in the main HTML/JS
file? Pre-parsed? Only half pregnant :) Never used JSObject .eval() but I'm
guessing that it does what JS.eval() does? (Never used JavaScript.eval()
either.)

You could call it from the Applet as well, but I would rather do the
JS stuff in JS instead of in Java.
Also, what am I gaining by imposing an eval() requirement in Function X that
couldn't be functionally achieved by just manipulating its parameters. IOW,
for a specific application it maybe useful for its JS function to
eval(param3) but for others function parameters 3 and 4 being strings and 5
the string representation of an int could suffice.

The method name as a parameter is more flexible than an argument
to a fixed method with a gigantic switch.
Surley one requires (de)serialization and the other does not? This matters
heaps to me! My kingdom for a generic 32 (or event 64) bit pointer :-(

Serialization and deserialization of a string is not a problem.
1a) Pass whatever context info that is needed as a string and, on return,
eval() it inside a variable (name-selected) JavaScript function. (Or perhaps
JSObject.eval())

1b) Pass whatever context-info is needed as strings and, on return, massage
the "arguments" array to a variable (name-selected) function.

2) Maintain a JavaScript Array of references to function instances (or other
complex Objects), one entry for each message sent. Fed from the tail and
removed from the head.

3) (de)Serialize a mythical pointer to an anonymous function/closure, and
pray that the JavaScript GC won't zap it before my Java Applet calls it.

Before consigning "3" to the dust-bin, let me just say that I really, really
liked the idea a lot!

I like "1b" but if "1a" has real advantages then I'm happy to hear them.

"2" is more along the lines of what I was trying to achieve but having to
maintain that queue-like Array (especially if the Socket is to be shared
among pages on different tabs and/or browser instances) requires something
to link-up several receieved messages and check that they were meant for
element[0]. (I'll ask about the possibility of gaps later on an inter-tab
question. . .)

So 1, 2 or 3? (And if 1 do you prefer "a" or "b"?)

1a

Least code and in the spirit of a dynamic language.

Arne
 
A

Arne Vajhøj

Richard said:
For some time (ever since a guy called Bojan Nemec told me about it :) I've
been toying with the idea of my Java Applet declaring its TCP/IP Socket as a
static class-variable instead of an instance-variable, and on each
invocation (new page, new tab, or new browser) the init() would check to see
if the Socket was already connected (and in my case User Authorization
completed) and, if so, skip that bit. Where I think it would be useful is
when there is a Control-Panel/Dashboard requirement, similar to what Arne
and another poster were discussing recently, where each browser "tab" was a
different set of instrumentation/view. All pages being servered by a single,
secure, feature-rich, connection-oriented, context-laden, and
high-performance Socket.

NB: If this is simply *just not doable* then please let me know now before I
spend a few days trying to get it to work :)

If the applet specs guarantee that multiple pages in different tabs
running the same value will share the same JVM, then it should work.

Andrew Thompson is probably the right guy to tell you if that
is the case.

In general I am not too keen on static stuff, but in your case
it could improve performance.
Some issues that spring to mind (that I hope someone can offer advice on)
are: -

1) To continue my "single reader-thread to oodles of writer-threads" model,
I'm really hoping that JSObject.getWindow() will return something that is
both unique to each web-page instance (wherever it is hosted) and the
accessible from my single reader thread. I plan to store it in a Linked-List
along with a Unique Id that will accompany the user request-messages on
their trips to the server and when they comes back, I'll search the list for
matching index-number, get the corresponding JSObject, and then perform the
.call(). (Perhaps JSObject is serializable? No wait - there's a toString()
method! What's the reverse? I'm guessing you can't simply cast the String as
JSObject.)

I would expect JSObject.getWindow() to return something different
for different pages.

A (Hash)Map sounds better as data structure than LinkedList to me.

Easy to look up by id.
2) I hope that JSObject.getWindow() returns the same thing in the Applet's
destroy() method as it does in the int() method so that I can do a reverse
lookup. Hey, there's a JSObject.equals() method - You bewdy!

I would expect so too.

But check.

The applet world has tricked people before.
3) The whole concept of Socket-Hijacking a la mode de Session-Hijacking, I'm
gonna leave to one side for the moment. I'm relying on Java to prohibit the
manual construction/fudge of a Java Socket on top of just any old socket,
and the operating system to protect a socket in one process/image from
access by another unprivileged process/image.

4) How do I prevent just any old page from including an <object> tag for my
Applet and gaining access to the (possibly pre-authorized) Socket? Off the
top of my head, I could store the Document Base of the first page that
actually passed authentication, and if any subsequent page comes from a
different DB then prompt for username/password again. Any other tools in the
toolbox that I can use to secure access?

Since they can already download your applet, decompile it, make
modifications and recompile it then you really can't prevent them
from doing stuff like that.

So I suggest that you do not waste to much time on that.
5) I'll have to introduce a logout function as that functionality is
currently enforced automatically by any page-change. I guess a dialog box
with some useless Socket statistics and a logout button should suffice.
(When the number of JSObjects is reduced to zero, an automatic logout will
take place.)

6) JRE instances. Funny how IE and FF don't share the same JRE instance :)
Even with Java 6 and up, as long as the Applets ask for the same Java
version then can there be every expectation that they'll share the same JRE
instance?

If the JVM were running in a separate process, then it would be
possible.

But if it is embedded with the browser process, then it can not be done.

Arne
 
R

Richard Maher

Hi Arne,

Arne Vajhøj said:
If the applet specs guarantee that multiple pages in different tabs
running the same value will share the same JVM, then it should work.

Seems to work.
Andrew Thompson is probably the right guy to tell you if that
is the case.

It is my impression that he would rather stick his head in a boiling
chip-pan than help someone develop an Applet over WebStart, but I would like
to know what the Apllet specs do guarantee.
In general I am not too keen on static stuff, but in your case
it could improve performance.

I'm looking more to functionality than performance.
I would expect JSObject.getWindow() to return something different
for different pages.

Me too. I'll test it out on HTML Framsets and iFrames; I'm expecting
adifferent JSObject per frame.
A (Hash)Map sounds better as data structure than LinkedList to me.

Easy to look up by id.

The problem is 99% of the time I will be looking up by IndexNumber and the
rest by JSObject. Someone recently showed me the Stack() class which looks
useful for reusing (in my case) message-slots, and a sequential search of an
ArrayList() loooks pretty fast.
I would expect so too.

But check.

I will.
The applet world has tricked people before.

You're not wrong!
Since they can already download your applet, decompile it, make
modifications and recompile it then you really can't prevent them
from doing stuff like that.

Yes they can do all that, but they can't stick their Applet in my codebase
of their web page in my document-base. The Applet sandbox is very useful in
this regard!
So I suggest that you do not waste to much time on that.

I'm trying to prevent the Frame or iFrame inclusion of my codebase HTML
inside a malicious wrapper-page; is this not a worthwhile exercise?
If the JVM were running in a separate process, then it would be
possible.

But if it is embedded with the browser process, then it can not be done.

Funny how it varies depending on File URLs as opposed to Web-Server URLs. No
matter, so far it looks like static class variables are shared between tabs
in a single browser instance if the host in the document-base is the same
and the code-base is the same.

Cheers Richard Maher
 
R

Richard Maher

Hi Arne,

Arne Vajhøj said:
If you have the function code on the page you only need to send
the name.
Yes.


You could call it from the Applet as well, but I would rather do the
JS stuff in JS instead of in Java.

The JSObject wrapper arround any old complex JavaScript object (as opposed
to returned by getWindow()) was the answer to my payers! Sadly it doe not
work in FireFox :-(
The method name as a parameter is more flexible than an argument
to a fixed method with a gigantic switch.


Serialization and deserialization of a string is not a problem.

Yes, but it's not just a string.
1a) Pass whatever context info that is needed as a string and, on return,
eval() it inside a variable (name-selected) JavaScript function. (Or perhaps
JSObject.eval())

1b) Pass whatever context-info is needed as strings and, on return, massage
the "arguments" array to a variable (name-selected) function.

2) Maintain a JavaScript Array of references to function instances (or other
complex Objects), one entry for each message sent. Fed from the tail and
removed from the head.

3) (de)Serialize a mythical pointer to an anonymous function/closure, and
pray that the JavaScript GC won't zap it before my Java Applet calls it.

Before consigning "3" to the dust-bin, let me just say that I really, really
liked the idea a lot!

I like "1b" but if "1a" has real advantages then I'm happy to hear them.

"2" is more along the lines of what I was trying to achieve but having to
maintain that queue-like Array (especially if the Socket is to be shared
among pages on different tabs and/or browser instances) requires something
to link-up several receieved messages and check that they were meant for
element[0]. (I'll ask about the possibility of gaps later on an inter-tab
question. . .)

So 1, 2 or 3? (And if 1 do you prefer "a" or "b"?)

1a

Least code and in the spirit of a dynamic language.

Arne

Cheers Richard Maher
 
J

Jon Gómez

Richard said:
The JSObject wrapper arround any old complex JavaScript object (as opposed
to returned by getWindow()) was the answer to my payers! Sadly it doe not
work in FireFox :-(

If this means you're making progress, I'm glad to hear that. :)
Jon.
 
R

Richard Maher

Hi Jon,

Jon Gómez said:
If this means you're making progress, I'm glad to hear that. :)

After 3 days of reading about the qualification process for submiting a bug
to Mozilla, I gave up. (Don't know if it is only FireFox it fails on or if
SeaMonkey works)

Anyway, being able to pass MyComplexMessageObject with its prototype
functions/methods and local data to Java (all while retaining a reference
one the JavaScript object) was the mutt's nuts! If only JSObject worked in
FF for other than getWindow() then it would be all gravy.

Anyway, back to preserving an array reference to the JavaScript Objects
while they're in Java land :-(

Cheers Richard Maher
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top