Name: gm110360 Date: 03/12/2002
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OPERATING SYSTEM VERSION :
Windows 98 [Version 4.10.2222]
A DESCRIPTION OF THE PROBLEM :
JavaScript numeric variables are returned to Java applets
by the Java 2 Plug-in with an Integer object wrapper. I was
expecting a Double object wrapper, because that is what you
get when using the "LiveConnect" interface under both
Netscape Navigator 4.x and Microsoft Internet Explorer, when
using their vendor-specific Java 1.1 support. (Note,
however, that Netscape's LiveConnect documentation claims
that numeric variables are returned in a Float wrapper; but,
in fact, that has never been the case, it has always been a
Double wrapper in both Netscape's and Microsoft's
implementations.)
This discrepancy causes existing LiveConnect applets to
crash, as they are coded to use a cast to Double, which
fails. A typical line of code is:
rows = ((Double)screen.getMember("rows")).intValue();
To get this to work with the Java 2 Plug-in, one can change
the code to:
rows = ((Integer)screen.getMember("rows")).intValue();
But then the applet will crash when run under older Web
browsers. However, there is a (rather awkward) "workaround"
which makes the code work in all cases. (See below.)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Code an applet and a Web page. The Web page must use
JavaScript to set some JavaScript variables and the Java
applet must issue "LiveConnect" calls to "getMember" to
retrieve the value of a numeric JavaScript variable.
2. Install the applet and Web page on a Web server.
3. Use a browser to access the Web page with the test
applet. Be sure the Java Console is activated.
4. Test the applet.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED:
The value of the numeric JavaScript variable is successfully
retrieved by the Java application.
ACTUAL:
The applet crashes, because it is coded to cast the returned
object to an object type that is different from what is
actually received.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ClassCastException: java.lang.Integer
at kb.init(kb.java:459)
at sun.applet.AppletPanel.run(AppletPanel.java:341)
at java.lang.Thread.run(Thread.java:536)
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.applet.Applet;
import java.awt.event.*;
import java.awt.Graphics;
import netscape.javascript.JSObject;
public class wraptest extends Applet implements KeyListener
{
JSObject win;
public void init()
{
win = JSObject.getWindow(this);
get_javascript_boolean();
get_javascript_int();
get_javascript_float();
get_javascript_string();
this.addKeyListener(this);
}
public void start()
{
requestFocus();
}
public void stop()
{
}
public void paint(Graphics g)
{
requestFocus();
// Draw a Rectangle around the applet's display area.
g.drawRect(0, 0, getSize().width - 1, getSize().height - 1);
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if (KeyEvent.VK_F1 <= key && key <= KeyEvent.VK_F12)
{
System.out.println("F" + (key + 1 - KeyEvent.VK_F1) + " key pressed.");
if (e.getKeyCode() == KeyEvent.VK_F9)
{
win.eval("ShowDecision()");
get_javascript_boolean();
requestFocus();
}
else if (e.getKeyCode() == KeyEvent.VK_F10)
{
win.eval("ShowAnswer()");
get_javascript_int();
requestFocus();
}
else if (e.getKeyCode() == KeyEvent.VK_F11)
{
win.eval("ShowPi()");
get_javascript_float();
requestFocus();
}
else if (e.getKeyCode() == KeyEvent.VK_F12)
{
win.eval("ShowMsg()");
get_javascript_string();
requestFocus();
}
e.consume();
}
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
void get_javascript_boolean()
{
Object obj;
Boolean b;
obj = win.getMember("decision");
if (obj != null)
{
System.out.println("\"decision\" returned wrapped as a " + obj.getClass().getName());
try
{
b = (Boolean)obj.getClass().getMethod("booleanValue", null).invoke(obj, null);
System.out.println("\"decision\" value is " + b.booleanValue());
}
catch (Exception e)
{
System.out.println("Could not convert \"decision\" to a \"boolean\"!");
}
}
else
System.out.println("\"decision\" is null!");
}
void get_javascript_int()
{
Object obj;
Integer i;
obj = win.getMember("answer");
if (obj != null)
{
System.out.println("\"answer\" returned wrapped as a " + obj.getClass().getName());
try
{
i = (Integer)obj.getClass().getMethod("intValue", null).invoke(obj, null);
System.out.println("\"answer\" value is " + i.intValue());
}
catch (Exception e)
{
System.out.println("Could not convert \"answer\" to an \"int\"!");
}
}
else
System.out.println("\"answer\" is null!");
}
void get_javascript_float()
{
Object obj;
Double d;
obj = win.getMember("pi");
if (obj != null)
{
System.out.println("\"pi\" returned wrapped as a " + obj.getClass().getName());
try
{
d = (Double)obj.getClass().getMethod("doubleValue", null).invoke(obj, null);
System.out.println("\"pi\" value is " + d.doubleValue());
}
catch (Exception e)
{
System.out.println("Could not convert \"pi\" to a \"double\"!");
}
}
else
System.out.println("\"pi\" is null!");
}
void get_javascript_string()
{
Object obj;
String s;
obj = win.getMember("msg");
if (obj != null)
{
System.out.println("\"msg\" returned wrapped as a " + obj.getClass().getName());
try
{
s = (String)obj.getClass().getMethod("toString", null).invoke(obj, null);
System.out.println("\"msg\" value is \"" + s.toString() + "\"");
}
catch (Exception e)
{
System.out.println("Could not convert \"msg\" to a \"String\"!");
}
}
else
System.out.println("\"msg\" is null!");
}
}
<HTML>
<HEAD>
<TITLE>JavaScript Variable Wrapper Test</TITLE>
</HEAD>
<SCRIPT>
var decision = true;
var answer = 42;
var pi = 3.14159;
var msg = "This is a test";
function ShowDecision()
{
alert("JavaScript variable \"decision\" is " + decision);
}
function ShowAnswer()
{
alert("JavaScript variable \"answer\" is " + answer);
}
function ShowPi()
{
alert("JavaScript variable \"pi\" is " + pi);
}
function ShowMsg()
{
alert("JavaScript variable \"msg\" is \"" + msg + "\"");
}
</SCRIPT>
<BODY>
Applet's Sandbox:
<P>
<APPLET MAYSCRIPT CODE="wraptest.class" WIDTH=64 HEIGHT=48>
</APPLET>
</BODY>
</HTML>
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Object obj = screen.getMember("rows");
try
{
rows =
(char)((Integer)obj.getClass().getMethod("intValue",
null).invoke(obj, null)).intValue();
}
catch (Exception ex)
{
}
(Review ID: 143976)
======================================================================
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OPERATING SYSTEM VERSION :
Windows 98 [Version 4.10.2222]
A DESCRIPTION OF THE PROBLEM :
JavaScript numeric variables are returned to Java applets
by the Java 2 Plug-in with an Integer object wrapper. I was
expecting a Double object wrapper, because that is what you
get when using the "LiveConnect" interface under both
Netscape Navigator 4.x and Microsoft Internet Explorer, when
using their vendor-specific Java 1.1 support. (Note,
however, that Netscape's LiveConnect documentation claims
that numeric variables are returned in a Float wrapper; but,
in fact, that has never been the case, it has always been a
Double wrapper in both Netscape's and Microsoft's
implementations.)
This discrepancy causes existing LiveConnect applets to
crash, as they are coded to use a cast to Double, which
fails. A typical line of code is:
rows = ((Double)screen.getMember("rows")).intValue();
To get this to work with the Java 2 Plug-in, one can change
the code to:
rows = ((Integer)screen.getMember("rows")).intValue();
But then the applet will crash when run under older Web
browsers. However, there is a (rather awkward) "workaround"
which makes the code work in all cases. (See below.)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Code an applet and a Web page. The Web page must use
JavaScript to set some JavaScript variables and the Java
applet must issue "LiveConnect" calls to "getMember" to
retrieve the value of a numeric JavaScript variable.
2. Install the applet and Web page on a Web server.
3. Use a browser to access the Web page with the test
applet. Be sure the Java Console is activated.
4. Test the applet.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED:
The value of the numeric JavaScript variable is successfully
retrieved by the Java application.
ACTUAL:
The applet crashes, because it is coded to cast the returned
object to an object type that is different from what is
actually received.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ClassCastException: java.lang.Integer
at kb.init(kb.java:459)
at sun.applet.AppletPanel.run(AppletPanel.java:341)
at java.lang.Thread.run(Thread.java:536)
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.applet.Applet;
import java.awt.event.*;
import java.awt.Graphics;
import netscape.javascript.JSObject;
public class wraptest extends Applet implements KeyListener
{
JSObject win;
public void init()
{
win = JSObject.getWindow(this);
get_javascript_boolean();
get_javascript_int();
get_javascript_float();
get_javascript_string();
this.addKeyListener(this);
}
public void start()
{
requestFocus();
}
public void stop()
{
}
public void paint(Graphics g)
{
requestFocus();
// Draw a Rectangle around the applet's display area.
g.drawRect(0, 0, getSize().width - 1, getSize().height - 1);
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if (KeyEvent.VK_F1 <= key && key <= KeyEvent.VK_F12)
{
System.out.println("F" + (key + 1 - KeyEvent.VK_F1) + " key pressed.");
if (e.getKeyCode() == KeyEvent.VK_F9)
{
win.eval("ShowDecision()");
get_javascript_boolean();
requestFocus();
}
else if (e.getKeyCode() == KeyEvent.VK_F10)
{
win.eval("ShowAnswer()");
get_javascript_int();
requestFocus();
}
else if (e.getKeyCode() == KeyEvent.VK_F11)
{
win.eval("ShowPi()");
get_javascript_float();
requestFocus();
}
else if (e.getKeyCode() == KeyEvent.VK_F12)
{
win.eval("ShowMsg()");
get_javascript_string();
requestFocus();
}
e.consume();
}
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
void get_javascript_boolean()
{
Object obj;
Boolean b;
obj = win.getMember("decision");
if (obj != null)
{
System.out.println("\"decision\" returned wrapped as a " + obj.getClass().getName());
try
{
b = (Boolean)obj.getClass().getMethod("booleanValue", null).invoke(obj, null);
System.out.println("\"decision\" value is " + b.booleanValue());
}
catch (Exception e)
{
System.out.println("Could not convert \"decision\" to a \"boolean\"!");
}
}
else
System.out.println("\"decision\" is null!");
}
void get_javascript_int()
{
Object obj;
Integer i;
obj = win.getMember("answer");
if (obj != null)
{
System.out.println("\"answer\" returned wrapped as a " + obj.getClass().getName());
try
{
i = (Integer)obj.getClass().getMethod("intValue", null).invoke(obj, null);
System.out.println("\"answer\" value is " + i.intValue());
}
catch (Exception e)
{
System.out.println("Could not convert \"answer\" to an \"int\"!");
}
}
else
System.out.println("\"answer\" is null!");
}
void get_javascript_float()
{
Object obj;
Double d;
obj = win.getMember("pi");
if (obj != null)
{
System.out.println("\"pi\" returned wrapped as a " + obj.getClass().getName());
try
{
d = (Double)obj.getClass().getMethod("doubleValue", null).invoke(obj, null);
System.out.println("\"pi\" value is " + d.doubleValue());
}
catch (Exception e)
{
System.out.println("Could not convert \"pi\" to a \"double\"!");
}
}
else
System.out.println("\"pi\" is null!");
}
void get_javascript_string()
{
Object obj;
String s;
obj = win.getMember("msg");
if (obj != null)
{
System.out.println("\"msg\" returned wrapped as a " + obj.getClass().getName());
try
{
s = (String)obj.getClass().getMethod("toString", null).invoke(obj, null);
System.out.println("\"msg\" value is \"" + s.toString() + "\"");
}
catch (Exception e)
{
System.out.println("Could not convert \"msg\" to a \"String\"!");
}
}
else
System.out.println("\"msg\" is null!");
}
}
<HTML>
<HEAD>
<TITLE>JavaScript Variable Wrapper Test</TITLE>
</HEAD>
<SCRIPT>
var decision = true;
var answer = 42;
var pi = 3.14159;
var msg = "This is a test";
function ShowDecision()
{
alert("JavaScript variable \"decision\" is " + decision);
}
function ShowAnswer()
{
alert("JavaScript variable \"answer\" is " + answer);
}
function ShowPi()
{
alert("JavaScript variable \"pi\" is " + pi);
}
function ShowMsg()
{
alert("JavaScript variable \"msg\" is \"" + msg + "\"");
}
</SCRIPT>
<BODY>
Applet's Sandbox:
<P>
<APPLET MAYSCRIPT CODE="wraptest.class" WIDTH=64 HEIGHT=48>
</APPLET>
</BODY>
</HTML>
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Object obj = screen.getMember("rows");
try
{
rows =
(char)((Integer)obj.getClass().getMethod("intValue",
null).invoke(obj, null)).intValue();
}
catch (Exception ex)
{
}
(Review ID: 143976)
======================================================================
- relates to
-
JDK-5100410 REGRESSION: Can't get String result from ActiveX Bridge component
-
- Closed
-