Software Development Work-arounds

Stopwatch icon If you see people coping with a problem you've already dealt with, maybe you should share that information to save them some time. Here's my attempt to do that.

Work-arounds for Annoying Problems

1. Why does XMLHttpRequest return bizarre status codes (e.g., 12030 and 12152) when posting to an HTTPS URL with MSIE?
2. How do I add a JavaFX scene graph to a Swing component?
3. How do I compile a program that uses the POSIX environ global variable on Solaris?

1.

Why does XMLHttpRequest return bizarre status codes (e.g., 12030 and 12152) when posting to an HTTPS URL with MSIE?

The only challenging aspect of client-side Web programming is the long history of bugs, incompatibilities, lack of standards compliance, and all-around poor implementation of many a Web browser.

This is an old problem whose cause is Microsoft Internet Explorer's (at least some versions) inability to process properly HTTP/1.1 keep-alives via SSL. The strange status codes are WinInet error codes, manifesting themselves with values of 12029, 12030, 12031, 12032, 1252, 1259, and possibly others. You can find a list of WinInet error codes in the WinInet API reference documentation. Internet Explorer 7.0 does not appear to have this problem. Therefore, one possible work-around is to detect the user agent on the server. If it's MSIE 6 or less, disable keep-alives. This work-around is simple to implement, but server-specific, so I do not provide example configuration directives.

Note, this work-around is useful only if you are deploying a Web application that must support MSIE 6 and you possess administrative control over the Web server. If you are writing a reusable JavaScript library for consumption by other developers, this work-around will not help you.

2.

How do I add a JavaFX scene graph to a Swing component?

One of the first things you try to do when experimenting with JavaFX is to add a JavaFX scene graph to a Swing component. As of JavaFX 1.1, there is no standard API for doing that. This is a class we used at my company to accomplish the task while evaluating JavaFX before deciding against using JavaFX.

/* * Copyright 2008 Savarese Software Research Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.savarese.com/software/ApacheLicense-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.savarese.jfx.ext.swing; import java.awt.BorderLayout; import javax.swing.JComponent; import javafx.reflect.FXClassType; import javafx.reflect.FXContext; import javafx.reflect.FXLocal; import javafx.reflect.FXObjectValue; import javafx.reflect.FXValue; public class JScene extends JComponent { public JScene(Object obj) throws Exception { setLayout(new BorderLayout()); FXClassType sceneImpl = FXContext.getInstance().findClass("com.sun.javafx.scene.JSGPanelSceneImpl"); FXObjectValue scene = sceneImpl.allocate(); scene.initVar("scene", FXLocal.getContext().mirrorOf(obj)); scene.initialize(); FXValue panel = sceneImpl.getVariable("jsgPanel").getValue(scene); add((JComponent)((FXLocal.ObjectValue)panel).asObject()); } }

Use the class as follows in your JavaFX code:

import javafx.ext.swing.SwingComponent; import com.savarese.jfx.ext.swing.JScene; import com.savarese.jfx.ext.swing.SplitPane; ... scene: Scene { content: [ ... SplitPane { left: ..., right: SwingComponent.wrap(new JScene(foo_scene)) } ] ... } ...

You'll notice the use of a custom SplitPane class. We had to implement custom MenuBar, Menu, MenuItem, etc., making JavaFX a waste of time for desktop apps. For interested parties, here's SplitPane:

/* * Copyright 2008 Savarese Software Research Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.savarese.com/software/ApacheLicense-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.savarese.jfx.ext.swing; import javafx.ext.swing.SwingComponent; import javax.swing.JSplitPane; public def HorizontalSplit : Integer = JSplitPane.HORIZONTAL_SPLIT; public def VerticalSplit : Integer = JSplitPane.VERTICAL_SPLIT; public class SplitPane extends SwingComponent { var split_pane: JSplitPane; public var orientation: Integer = HorizontalSplit on replace { split_pane.setOrientation(orientation); } public var left: SwingComponent on replace { split_pane.setLeftComponent(left.getJComponent()); } public var right: SwingComponent on replace { split_pane.setRightComponent(right.getJComponent()); } protected override function createJComponent() { split_pane = new JSplitPane(); return split_pane; } }

3.

How do I compile a program that uses the POSIX environ global variable on Solaris?

Solaris doesn't declare extern char **environ; in <unistd.h>, but does define it in its standard C library. Therefore you can simply add something like the following to your program:

#if defined(HAVE_DECL_ENVIRON) && !HAVE_DECL_ENVIRON # ifdef __cplusplus extern "C" { # endif extern char **environ; # ifdef __cplusplus } # endif #endif

Using autoconf, you can define HAVE_DECL_ENVIRON by placing the following in configure.ac:

AC_CHECK_DECLS_ONCE([environ])

More to come …