Customer is seeing a NPE.
Error: java.lang.NullPointerException
at java.awt.Window.<init>(Window.java:197)
at java.awt.Frame.<init>(Frame.java:310)
at java.awt.Frame.<init>(Frame.java:257)
at com.epiphany.charts.roguewave.ChartFactory.getGIFRepresentation(ChartFactory.java:209)
at com.epiphany.charts.roguewave.ChartFactory.createChart(ChartFactory.java:271)
at com.epiphany.charts.CreateChartAction.execute(CreateChartAction.java:111)
at com.epiphany.server.CommandThread.execute(CommandThread.java:301)
at com.epiphany.server.CommandThread.runInternal(CommandThread.java:160)
at com.epiphany.server.EpiThread.run(EpiThread.java:96)
###@###.### 2003-11-03

EVALUATION
Reproducible as described.
###@###.### 2003-11-04
Leaving a Java app running, locking the remote machine, disconnecting, and then reconnecting was not a problem with a "normal" app, such as SwingSet or
Java2Demo. The test case, though, boils down to:
while(weHaven'tDiedYet) {
Frame f = new Frame();
f.pack();
f.dispose();
}
So, even after disconnecting, the test will still (try to) create native backing
windows.
The NPE comes from this swatch of code in Window.java:
Rectangle screenBounds = graphicsConfig.getBounds();
Insets screenInsets = getToolkit().getScreenInsets(graphicsConfig);
---> int x = getX() + screenBounds.x + screenInsets.left;
int y = getY() + screenBounds.y + screenInsets.top;
screenBounds is coming up null, and we NPE on the indicated line. Here's where
the null comes from:
Java_sun_awt_Win32GraphicsConfig_getBounds(JNIEnv *env, jobject thisobj,
jint screen) {
...
jobject bounds = NULL;
...
if( TRUE == ::MonitorBounds(AwtWin32GraphicsDevice::GetMonitor(screen),
&rRW) ) {
bounds = env->NewObject(clazz, mid,
rRW.left, rRW.top,
rRW.right - rRW.left,
rRW.bottom - rRW.top);
...
}
... return bounds;
}
::MonitorBounds fails, presumably because our cached MHND is no longer valid
after we disconnect from the remote session. bounds remains NULL, and is
returned as such.
The customer works around this in their JDK by not using screenBounds if
it's null (see the Work Around). This may work with 1.3.1_09 and/or 1.4.2_02 (I
didn't try), but I've found that with 1.5 it turns ths exception into a crash. ;(
The crash comes when AwtComponent::SetBackgroundColor() tries to use an array
index of -1. Observe:
void AwtComponent::SetBackgroundColor(COLORREF c)
{
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen);
if (grayscale != GS_NOTGRAY) {
...
The basic idea is to get from AwtComponent to grayness via:
HWND->MHND->index into our array of devices->grayness of the device at that index.
The HWND->MHND step is done by the win32 function
::MonitorFromWindow()
called from
AwtWin32GraphicsDevice::DeviceIndexForWindow().
The MHND->index step is done by
getScreenFromMHND()
in
awt_Win32GraphicsEnv.cpp.
So, we get the MHND for our HWND, and look through our cached
AwtWin32GraphicsDevices for that MHND:
int getScreenFromMHND(MHND mon) {
DASSERT(mon != NULL);
for (int i = 0; i < awt_numScreens; i++) {
if (areSameMonitors(mon, getMHNDFromScreen(i))) {
return i;
}
}
return -1;
}
HOWEVER
When we disconnect from the remote server, ::MonitorFromWindow() starts
returning MHNDs we've never seen. I assume it does some sort of display change. At any rate, getScreenFromMHND() nevers finds it, and returns -1.
At first I thought that this problem might be addressed by fixing:
4417798 : Need to track add/remove of monitors on display changes
but from my debugging statements it looks like the crash happens before we see
the WM_DISPLAYCHANGE. event.
My fix has two parts:
1) Return the bounds of the primary monitor from Win32GraphicsConfig.getBounds()
instead of null in the case that ::MonitorBounds() fails. This prevents the NPE
in Window.java (and anywhere else that might call GC.getBounds()).
2) Return default idx (usually 0) instead of -1 from getScreenFromMHND()
This keeps things running, though in a bit of a weird state, since without
4417798 our AwtWin32GraphicsDevice array is never updated. But it doesn't NPE
or crash.
###@###.### 2003-11-25